天天看点

第112期:前端性能监控的实现方案思考(一)

这里记录工作中遇到的技术点,以及自己对生活的一些思考,周三或周五发布。

封面图

第112期:前端性能监控的实现方案思考(一)

通常情况下我们不会遇到前端性能监控的需求,但是当我们的关键项目真的有这个需求的时候应该怎么做呢?

我们通常会接入第三方的监控API,但是如何实现这种监控,也是我们需要思考的问题,只有从全局出发,思考前端监控的实现发案,我们才能从这个思考的过程中有所收获。

上图是我对前端性能监控的一些思考,当然,这个图表示的只是一个思考的过程,具体的实施,需要我找时间去画另一张图,实施图,可能就包括的比较详细一些,数据格式的定义,数据上报的实现方式,页面监控的实现方案等等。

监控什么

前端监控通常情况下监控的内容可以分为三类:

第一,js错误。

js错误又分大概四种:一是​

​uncaught error​

​​,这种错误通常情况下发生在我们的开发过程中。理论上不需要我们进行上报。二是​

​js runtime error​

​​, 这种错误会触发​

​window.onerror​

​​事件,我们可以通过监听onerror事件,获取到相关的信息进行上报。三是资源错误,比如图片加载失败等,它也会触发error事件。四是​

​unhandledregection​

​​错误,这种错误由promise触发,我们可以监听​

​onunhandledrejection​

​方法获取相关信息进行上报。

第二,用户行为。

用户行为大体上可以理解为,谁,在什么时间,做了哪些操作。比如,用户,登录了什么应用,应用的版本是什么,应用所在的平台信息,页面的访问情况,停留时长等。

第三,应用的性能。

应用的性能指的是,比如页面加载时长,接口请求时长,资源大小等等。

以哪种方式进行监控

监控方式,其实指的就是我们平常说的埋点方式。通常情况分为自动埋点,和手动埋点。

自动埋点的实现方式稍微复杂一些,需要我们去hack很多内容。比如需要重写​

​XHR​

​​对象,或者已一种更优雅的方式实现​

​fetch​

​等。

而手动埋点则是我们直接在业务代码中需要监控的地方,直接调用接口上报所需的数据即可。

简单高效,但是繁琐。

自动监控,自动上报数据时。我们需要考虑以哪种方式进行上报比较好一些,比如开启定时任务,或者开启任务队列。每隔一分钟上报一次数据,或者每10条,20条数据上报一次。以免上报逻辑对应用本身产生不好的影响。

数据格式如何定义

根据我们需要上报的信息,我们可以先把需要上报的数据格式先简单定义一下。

对于JS错误,我们需要知道错误信息,发生错误的代码,代码行号以及列号。

interface JsErrorInfo {
     msg:string,
     source:string,
     lineno:number,
     colno:number,
     ...
 }      

对于用户行为,我们需要知道当前用户是谁,用户使用的什么平台,登陆的什么应用,当前应用是哪个版本,用户进行什么样的操作,用户所在的页面地址,甚至当前页面的路由模式,以及是页面是否带有参数。

interface UserActionInfo {
    userId:string,
    platform:string,
    appType:string,
    appld:string,
    appVersion:string,
    userAction:string, // click
    timeStamp:number, // time
    visitedUrl:string,
    visitedUrlMode:string,
    visitedParams:any,
    ...
}      

对于页面性能,我们需要了解一些基本的性能指标及监听方式。

PerfInfo {
    currentUrl:string,
    source:string,
    requestUrl:string,
    loadtime:string,
    size:size,
    ...
}      

API如何定义?

当我们从整体上有一个思路之后,我们就可以思考如何对外提供一套api。 API如何定义呢?

通常情况下都会提供一个构造函数,然后通过init方法进行初始化。

例如:

import {Vue} from 'vue

let myApp = new Vue(config)      

亦或是通过定义方法来示例化新的对象:

import {createApp} from 'vue

let myApp = createApp(config)      

有了这个思考的流程之后,我们只需要思考我们的构造函数需要哪些方法,然后不断的去完善即可。比如:上报信息方法,监听错误信息,计算页面加载时间,生成任务队列...

最后

最近的事情太多了,这一篇只是一个思考的过程,后面会有一个简单的实现过程,接口如何定义,如何计算相关指标等等。

继续阅读