使用PerformanceObserver监控页面性能
更新于 阅读 2 次
下图显示了PerformanceNavigationTiming中定义的所有时间戳属性
下面来获取这些时间属性:
const observer = new PerformanceObserver((list) => { list.getEntries().forEach((entry) => { console.log(entry.toJSON()); }); }); observer.observe({ entryTypes: ["navigation"] });
可以通过在线demo查看,这样就可以来计算各个性能指标了
{ "name": "http://localhost:3000/TinyCode", "entryType": "navigation", "startTime": 0, "duration": 1428, "initiatorType": "navigation", "deliveryType": "", "nextHopProtocol": "http/1.1", "renderBlockingStatus": "non-blocking", "workerStart": 0, "redirectStart": 0, "redirectEnd": 0, "fetchStart": 1.299999998882413, "domainLookupStart": 1.299999998882413, "domainLookupEnd": 1.299999998882413, "connectStart": 1.299999998882413, "secureConnectionStart": 0, "connectEnd": 1.299999998882413, "requestStart": 2.5, "responseStart": 282.19999999925494, "firstInterimResponseStart": 0, "finalResponseHeadersStart": 282.19999999925494, "responseEnd": 283, "transferSize": 1392, "encodedBodySize": 1092, "decodedBodySize": 2123, "responseStatus": 200, "serverTiming": [ ], "unloadEventStart": 285.7999999988824, "unloadEventEnd": 285.7999999988824, "domInteractive": 302.8999999985099, "domContentLoadedEventStart": 1277.2999999988824, "domContentLoadedEventEnd": 1277.2999999988824, "domComplete": 1427.5999999996275, "loadEventStart": 1428, "loadEventEnd": 1428, "type": "reload", "redirectCount": 0, "activationStart": 0, "criticalCHRestart": 0, "notRestoredReasons": null }
下面是一些指标的介绍:
- name:导航地址
- startTime: 开始时间
- duration:导航过程耗费的时间(loadEventEnd - startTime的值)
- fetchStart:浏览器开始获取资源之前的时间
- domainLookupStart:浏览器开始查找DNS之前的时间
- domainLookupEnd:浏览器查找到DNS的时间
- connectStart:http开始建立连接的时间
- connectEnd:http连接建立完成的时间
- requestStart: 浏览器开始从服务器、缓存或本地资源请求资源之前的时间的时间戳。如果传输连接失败且浏览器放弃请求,则返回的值将是重试请求的开始时间。
- responseStart: 在浏览器从服务器、缓存或本地资源接收到响应的第一个字节后立即返回一个时间戳。
- responseEnd: 相应全部接受完成的时间
- domInteractive: 浏览器完成所有DOM的解析并且DOM树完成构建的时间点
- domContentLoadedEventStart: 处理DOMContentLoaded事件之前的时间
- domContentLoadedEventEnd: 处理DOMContentLoaded后的时间,domContentLoad完成后才会生成render树,cssom树的构建需要根据是否在dom解析中js是否操作样式,如果需要那么cssom就是在domInteractive之前完成,否则在domContentLoaded后完成。
- domComplete: dom处理完成,并且资源/图片都加载完成。
- loadEventStart: load事件处理之前的时间
- loadEventEnd: load事件处理完成后的时间
然后就可以来计算网页加载过程中的性能指标了,下面是从掘金的文章中copy的一个计算逻辑然后稍加改造的代码
function process(pnt) { const column = [ { key: 'Redirect', desc: '网页重定向的耗时', value: pnt.redirectEnd - pnt.redirectStart, }, { key: 'AppCache', desc: '检查本地缓存的耗时', value: pnt.domainLookupStart - pnt.fetchStart, }, { key: 'DNS', desc: 'DNS查询的耗时', value: pnt.domainLookupEnd - pnt.domainLookupStart, }, { key: 'TCP', desc: 'TCP连接的耗时', value: pnt.connectEnd - pnt.connectStart, }, { key: 'Waiting(TTFB)', desc: '从客户端发起请求到接收到响应的时间 / Time To First Byte', value: pnt.responseStart - pnt.fetchStart, }, { key: '白屏时间', desc: '首次渲染时间/白屏时间', value: pnt.responseStart - pnt.startTime, }, { key: 'Content Download', desc: '下载服务端返回数据的时间', value: pnt.responseEnd - pnt.responseStart, }, { key: 'request', desc: 'request请求耗时', value: pnt.responseEnd - pnt.requestStart, }, { key: 'dom树', desc: '解析dom树耗时', value: pnt.domComplete - pnt.domInteractive, }, { key: 'DOMContentLoaded', desc: 'dom加载完成的时间', value: pnt.domContentLoadedEventEnd, }, { key: 'Loaded', desc: '页面load的总耗时', value: pnt.duration }, ]; console.table(column); } const observer = new PerformanceObserver((list) => { list.getEntries().forEach((entry) => { console.log(entry.toJSON()); process(entry.toJSON()); }); }); observer.observe({ entryTypes: ["navigation"] });
这是我的个人后台系统打印的时间 :