首页
学习
活动
专区
工具
TVP
发布

浅谈前端对于系统和用户行为的获知

前言

是否担心过上线的工程有隐藏的bug而自己不知道?是否怀疑过用户不会按照我们期望的轨迹去操作?系统和用户行为的获知,对于系统问题的修复、用户体验的优化和产品后续的迭代是有很大的参考意义的。那么,当我们开发完成一个项目并将其上线后,如何获知其系统有没有正常工作、性能有没有遇到瓶颈、用户体验有没有符合预期呢?本文将就此主题进行一些简述。

如何获知

我们如何获知系统和用户的行为呢?简而言之,即采集、上报、分析与聚合。行为是可以转化成数据的。在采集到行为后,将其转化成数据,再上报到统一的数据平台中,进行相应的分析和聚合,获取到我们真正需要的、容易理解的信息,如用户转化率的报表、定时推送的系统状态、出现异常时的报警等。

本文主要简述上图中的第一步,即需要采集的行为和如何采集。

系统行为

系统行为,即线上的工程所表现的行为,如代码逻辑有无报错、静态资源是否请求成功、接口是否正常返回、页面加载性能如何等,代表了我们系统的健康度。下面列举几个需要我们关注的系统行为。

1.JavaScript异常

JavaScript异常,代表代码某处逻辑出现问题我们的代码或所依赖的代码运行出现错误时,就会抛出JavaScript异常。通过收集JavaScript异常并进行监控,可以尽早发现代码逻辑中存在的大大小小的问题。采集方法简述:通过window.onerror方法可以全局捕获到JS异常,并可以携带source、lineno、colno等信息,来定位到错误发生处。但由于浏览器的同源性策略的限制,对于js文件域名与当前页面的域名不同的情况,error对象的message会被替换为'Script error.',我们就无法获知具体的异常是什么。我们可以通过js文件的HTTP请求返回的Access-Control-Allow-Origin这一Header,与script标签的crossorigin属性来绕过。在系统较复杂的情况下,由于依赖很多、代码压缩、运行商劫持等等原因,JavaScript异常的可读性和价值会比较差。所以在很多我们可控的场景下,也可以手动抛出异常。

window.onerror=(message,source,lineno,colno,error)=>{

// 处理与上报

}

doSomething().then(()=>{

// ...

}).catch(()=>{

thrownewError('[throw] doSomething failed')

})

需要注意的是,在上报过程中,如果直接使用JSON.stringify来序列化一个Error对象,会丢失其message,因为Error对象的message属性是不可枚举的。我们需要手动去构造一个新的上报数据格式。

2.静态资源异常

静态资源异常,代表所依赖的js/css/img资源无法正常加载,视资源的重要程度,会导致不同程度的问题静态资源异常,如主js文件加载失败,会导致整个系统都无法正常工作;如某个css文件加载失败,会导致页面的样式会出现问题。在不考虑由于构建过程或代码逻辑导致的资源地址错误的情况下,静态资源异常通常代表了服务器或cdn不能正常响应HTTP请求,通过持续监控资源的成功率,可以尽早发现其出现的风险和问题,并加以改进。采集方法简述:当一个资源加载失败的时候,加载资源的元素会触发一个error事件。这个error事件不会向上冒泡到window,但是可以被window.addEventListener捕获到。故我们可以使用如下的方法采集到静态资源的异常:

// 捕获阶段,第三个参数需为true

window.addEventListener('error',(event)=>{

consttarget=event.target

// 分别代表js/css/img资源

if(targetinstanceofHTMLScriptElement

||targetinstanceofHTMLLinkElement

||targetinstanceofHTMLImageElement){

// 处理与上报

}

},true)

3.ajax接口异常

ajax接口异常,代表处理请求过程中出现错误,通常会导致用户的操作无法正常得到响应ajax接口异常,通常和前端或后端系统代码的逻辑有关。如提交订单接口请求后有没有正确生单,就这一场景来说,可能是因为前端所传参数有误,也可能是因为后端系统处理请求过程中出现问题。不论是何种场景,都代表着系统的某个环节出现问题的,需要我们及时发现并跟进解决。采集方法简述:ajax接口异常有两种场景:

HTTP请求失败,如400 Bad Request、500 Internal Server Error等

HTTP请求成功,但后端返回的响应结果是失败的

由于接口定义等的差异,第二种场景的异常是不易进行自动采集的。故对于ajax接口异常,可以通过手动采集上报的方式来进行。

// 以fetch为例

fetch(url).then((res)=>{

if(res.ok&&res.status===200&&res.body){

res.json().then((data)=>{

// 此处通过接口定义的是否成功字段判断

if(data.status===){

// ...

}else{

// 第二种场景,处理与上报

}

});

}else{

// 第一种场景,处理与上报

}

})

4.性能

性能,广泛来讲,包括页面的加载性能、接口的响应时间等,前端所关注的主要在于第一点即页面的加载性能通常我们会关注几个关键阶段:首字节时间、可交互时间、完全加载时间,分别代表了开始构建DOM、DOM构建完成、所有内容全部加载完成所需的时间。持续监控与优化页面的加载性能,对于提升用户体验是有比较大的帮助的。采集方法简述:页面加载性能的采集,可以通过Performance接口。我们所主要关注的三个阶段,与Performace接口的对应关系如下:

首字节时间:domLoading

可交互时间:domInteractive

完全加载时间:loadEventEnd

用户行为

用户行为,即用户访问了哪些页面、停留了多久、进行了什么操作等,通过获知完整的用户行为,可以还原用户的操作路径,为系统问题的发现、产品设计的优化打下基础。

1.浏览行为

浏览行为,即pv(Page View),指用户浏览了某个页面,浏览行为的数据是很多数据分析的基础。此行为可通过Nginx/Apache层的日志获知,也可以通过在前端代码中采集上报。前端采集方式可分为自动和手动两种,自动即在页面加载之后,上报当前页面的Url;手动即在代码中调用上报接口,可以携带一些自定义信息。

2.操作行为

操作行为,如用户的点击行为、页面滑动行为等。通过记录这一行为,可以还原用户的操作路径,是复现问题、优化产品等的数据基础。采集方式通常为在行为发生后手动上报。浏览和操作行为的采集上报较简单,直接构造所需数据格式上报即可。

环境信息

那么,需要除了对应行为的数据,我们还需要什么额外的信息呢?在避开采集用户敏感信息的前提下,我们需要尽可能多的获知行为发生时的环境。故用户的ip与地区、浏览器与操作系统的版本(User Agent)、行为产生时的页面的Url,都是我们需要的信息。在上报时,是需要一并携带的。

结语

构建上述的采集sdk与数据平台也是很多公司都在做的事情。本文所述的采集方法较为简单,但在实际的构建过程中,会涉及到很多复杂的场景与瓶颈。作为一个前端工程师,不能把自己局限在完成业务的开发上,我们是需要知道系统有没有正常工作、用户行为符不符合我们的预期的,没有任何行为的上报就“裸奔上线”是很危险的。不论是自己构建,还是使用开源的、公司体系的,希望本文能给你一些启发~

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180307G0HVUZ00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券