1.性能分析
既然是性能分析,那么我们首先要了解各个性能指标。根据W3C Navigation Timing Level 2的规范标准,可以通过 window.performance.timing 获取具体资源的详细耗时信息。
1.1、首字节(TTFB)
TTFB 即 Time To First Byte,指用户首次请求web服务器和服务器响应到终端用户之间这段时间。
1.2、白屏时间
浏览器开始显示内容的时间。因为浏览器在不断接收和处理其余内容的同时,呈现引擎会将部分内容解析并显示出来,并不必等到整个 HTML 文档解析完毕之后才去开始构建呈现树和设置布局。所以我们通常可以认为是浏览器解析完 <head> 的时刻或开始渲染 <body> 标签就是页面白屏结束的时间。
performance.timing.domLoading - performance.timing.navigationStart
1.3、首屏时间
用户看到第一屏页面所消耗的时间。对于用户体验来说,这是一个非常重要的体验因素。我们可以以白屏结束时间作为首屏开始时间,通过onload的触发来作为首屏结束时间。(不能通过DocumentContentLoaded,因为他是在DOM树加载完之后触发,但图片等静态资源还没有完成请求。)
<script> window.onload = function(){ const onLoadTime = new Date().getTime(); const navigationStartTime = window.performance.timing.navigationStart; const firstScreenTime = onLoadTime - navigationStartTime; console.log('首屏时间-----', firstScreenTime); } </script>
还可以通过MutationObserver 来计算首屏时间, 他提供了监视对DOM树所做更改的能力。
<script> // 选择监听变动的节点 const bodyDom = document.body || document; // 配置变动条件 const config = { attributes: true, childList: true, subtree: true }; // 变动发生后的回调 const callbackFn = function(mutationsList, observer){ console.log('节点发生变动时间----', mutationsList, new Date().getTime()); } // 创建实例并传入回调函数 const observer = new MutationObserver(callbackFn); // 开始监听目标节点 observer.observe(bodyDom, config); // 停止监听 // observer.disconnect(); </script>
1.4、总下载时间
页面所有资源加载完成所的时间。可以通过 window.onload 的触发时间来获取。
2.错误收集
那对于前端来讲,错误往往会阻塞程序运行,给用户极其不好的体验。那么我们可以提前对错误有所准备,第一时间将错误捕获,拿到错误信息并及时做出反应。
2.1、onerror
只需一个方法即可全局捕获运行时错误(包括处理程序中引发的语法错误)和普通异步错误,但是不能捕获静态资源加载错误,接口请求错误,Promise错误。
<script> window.onerror = function(msg, source, row, col, error){ console.log('错误信息-----', msg); console.log('错误地址-----', source); console.log('错误行号-----', row); console.log('错误列号-----', col); console.log('错误对象-----', error); } </script> <script> // 语法错误 // const person.name; // 异步错误 // setTimeout(() => { // fn(); // }, 500) // promise错误 //new Promise((resolve, reject) => { reject('出错啦---') }) </script>
onerror针对跨域脚本的错误捕获需要进行特殊处理, 要对script 脚本设置crossorigin,同时服务器添加 Access-Control-Allow-Origin 以指定允许哪些域的请求访问。
2.2、addEventListener - error
与onerror雷同,但是可以捕获静态资源加载错误
<script> window.addEventListener('error', function(event){ console.log('错误信息-----', event); }, true) </script>
2.3、addEventListener - unhandledrejection
可以捕获未处理的Promise错误,但是兼容性较差。
<script> window.addEventListener('unhandledrejection', function(event){ console.log('错误信息-----', event); }, true); new Promise((resolve, reject) => { reject('出错啦---') }); </script>
2.4、try...catch
只能捕获代码块内的同步执行的错误,不能捕获其他错误。
<script> try{ fn() }catch(error){ console.log("同步执行错误---", error) } try{ setTimeout(() => { fn() }, 500) }catch(error){ console.log("异步错误---", error) } try{ new Promise((resolve, reject) => { reject('出错啦---') }) }catch(error){ console.log("Promise错误---", error) } try{ console.123); }catch(error){ console.log("语法错误---", error) } </script>