AboutFE
AboutFE copied to clipboard
47、前端监控
- FP,全称 First Paint,翻译为首次绘制,是时间线上的第一个时间点,它代表网页的第一个像素渲染到屏幕上所用时间,也就是页面在屏幕上首次发生视觉变化的时间。(performance.getEntriesByType('paint')[0].startTime)
- FCP,全称 First Contentful Paint,翻译为首次内容绘制,顾名思义,它代表浏览器第一次向屏幕绘内容。(注意:只有首次绘制文本、图片(包含背景图)、非白色的canvas或SVG时才被算作FCP) (通过performance.getEntriesByType('paint’),取第二个pain的时间,或者通过Mutation Observer观察到首次节点变动的时间)
- FMP,全称 First Meaningful Paint,翻译为首次有意义的绘制,是页面主要内容出现在屏幕上的时间, 这是用户感知加载体验的主要指标。目前尚无标准化的定义, 因为很难以通用的方式去确定各种类型页面的关键内容
window.performance、 PerformanceObserver 的自定义玩法监控
- 白屏时间
- HTML 加载完成时间
- 首屏图片加载完成时间
- 首屏接口完成加载完成时间
- 各资源耗时(主要统计css/js资源耗时)
- FP(首次绘制时间)
- FCP(首次内容渲染时间)
- onload时间
一、为什么要处理异常?
异常是不可控的,会影响最终的呈现结果,但是我们有充分的理由去做这样的事情。
- 增强用户体验;
- 远程定位问题;
- 未雨绸缪,及早发现问题;
- 无法复线问题,尤其是移动端,机型,系统都是问题;
- 完善的前端方案,前端监控系统;
对于 JS 而言,我们面对的仅仅只是异常,异常的出现不会直接导致 JS 引擎崩溃,最多只会使当前执行的任务终止。
二、需要处理的异常分类
- JS 语法错误、代码异常 (try-catch 只能捕获到同步的运行时错误,对语法和异步错误却无能为力,捕获不到。onerror 主要是来捕获预料之外的错误,而 try-catch 则是用来在可预见情况下监控特定的错误,两者结合使用更加高效)
- AJAX 请求异常
- 静态资源加载异常 (window.addEventListener('error')
- Promise 异常 (catch + window.addEventListener("unhandledrejection")
- Iframe 异常 ( window.frames[0].onerror)
- 跨域 Script error (改写了 EventTarget 的 addEventListener 方法;对传入的 listener 进行包装,返回包装过的 listener,对其执行进行 try-catch;浏览器不会对 try-catch 起来的异常进行跨域拦截,所以 catch 到的时候,是有堆栈信息的;重新 throw 出来异常的时候,执行的是同域代码,所以 window.onerror 捕获的时候不会丢失堆栈信息;利用包装 addEventListener,我们还可以达到「扩展堆栈」的效果)
(() => {
const originAddEventListener = EventTarget.prototype.addEventListener;
EventTarget.prototype.addEventListener = function (type, listener, options) {
+ // 捕获添加事件时的堆栈
+ const addStack = newError(`Event (${type})`).stack;
const wrappedListener = function (...args) {
try {
return listener.apply(this, args);
}
catch (err) {
+ // 异常发生时,扩展堆栈
+ err.stack += '\n' + addStack;
throw err;
}
}
return originAddEventListener.call(this, type, wrappedListener, options);
}
})();
- 崩溃和卡顿 (利用 window 对象的 load 和 beforeunload 事件实现了网页崩溃的监控, 或者 service worker 有自己独立的工作线程,与网页区分开,网页崩溃了,Service Worker 一般情况下不会崩溃;Service Worker 生命周期一般要比网页还要长,可以用来监控网页的状态;网页可以通过 navigator.serviceWorker.controller.postMessage API 向掌管自己的 SW 发送消息)
- vue react (Vue.config.errorHandler, react componentDidCatch)