背景
衡量页面性能的方式。
概念
首屏范围的界定:【top: 0, left: 0, width: 100vw, height: 100vh】
这里的首屏指代,页面首次加载时,当前屏幕内 DOM 内容。
针对首屏时间的计算,目前只考虑包含图片和不包含图片的场景
首屏有图片
首屏时间 = 首屏图片全部加载完毕时刻 - window.performance.timing.navigationStart
首屏无图片
首屏时间 = 页面处于稳定状态前最后一次 DOM 变动的时刻 - window.performance.timing.navigationStart
背景图片的加载不会触发 DOM 的变动
实现原理
从页面加载开始,按照一定间隔打点,记录首屏 DOM 变动时刻 T1
记录打点时刻,首屏内图片的加载完成时刻(performance.timing 中获取)T2
找出 DOM 的最后变动时的打点时刻 T1‘,以及此刻首屏内最后一张图片的加载完成时刻 T2’
对比 T1‘ 和 T2’,取较大者作为首屏时间
如何获取首屏内图片的加载完成时刻?
基于 MutationObserver
的监听操作不适用于图片的加载,图片的加载不会触发 MutationObserver
的响应。
此时要依赖 PerformanceObserver
,通过监听资源的变动情况,结合判断该资源是否属于首屏,来确定首屏内图片的最后完成时刻。
const observer = new PerformanceObserver(list => {
// new added resource entries
const entries = list.getEntries();
});
observer.observer({ entryTypes: ['resource'] });
指标
FMP(First Meaning Paint):首次有效绘制(是否可用时间点)
参数说明
具体文字说明:
- navigationStart 加载起始时间
- redirectStart 重定向开始时间(如果发生了HTTP重定向,每次重定向都和当前文档同域的话,就返回开始重定向的fetchStart的值。其他情况,则返回0)
- redirectEnd 重定向结束时间(如果发生了HTTP重定向,每次重定向都和当前文档同域的话,就返回最后一次重定向接受完数据的时间。其他情况则返回0)
- fetchStart 浏览器发起资源请求时,如果有缓存,则返回读取缓存的开始时间
- domainLookupStart 查询DNS的开始时间。如果请求没有发起DNS请求,如keep-alive,缓存等,则返回fetchStart
- domainLookupEnd 查询DNS的结束时间。如果没有发起DNS请求,同上
- connectStart 开始建立TCP请求的时间。如果请求是keep-alive,缓存等,则返回domainLookupEnd
- (secureConnectionStart) 如果在进行TLS或SSL,则返回握手时间
- connectEnd 完成TCP链接的时间。如果是keep-alive,缓存等,同connectStart
- requestStart 发起请求的时间
- responseStart 服务器开始响应的时间
- domLoading 从图中看是开始渲染dom的时间,具体未知
- domInteractive 未知
- domContentLoadedEventStart 开始触发DomContentLoadedEvent事件的时间
- domContentLoadedEventEnd DomContentLoadedEvent事件结束的时间
- domComplete 从图中看是dom渲染完成时间,具体未知
- loadEventStart 触发load的时间,如没有则返回0
- loadEventEnd load事件执行完的时间,如没有则返回0
- unloadEventStart unload事件触发的时间
- unloadEventEnd unload事件执行完的时间
使用
DNS解析时间: domainLookupEnd - domainLookupStart
TCP建立连接时间: connectEnd - connectStart
白屏时间: responseStart - navigationStart
dom渲染完成时间: domContentLoadedEventEnd - navigationStart
页面onload时间: loadEventEnd - navigationStart
结果
var timing = performance.timing;
var times = {
redirect:timing.redirectEnd - timing.redirectStart,
lookupDomain:timing.domainLookupEnd - timing.domainLookupStart,
connect:timing.connectEnd - timing.connectStart,
request:timing.responseEnd - timing.requestStart
};
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。