引言
在平时工作中可能会遇到用户反馈:“哥们,你们的网站感觉很卡啊!”。这种来自用户的吐槽对前端同学可以说是直击心灵的冲击。此时就应该好好想想如何让用户不再出现这样的吐槽呢。首先就是指标化的了解自己的网站。
常用的衡量指标
可以结合两张图
第一张图是浏览器加载整个页面的时间线,第二张图则是这个是Google力推的指标,主要从4个视觉反馈阶段来描述页面性能。
总结一下常用的性能指标
- 白屏时间:白屏时间是指浏览器从响应用户输入网址地址,到浏览器开始渲染内容的时间。
- 首屏时间:首屏时间是指浏览器从响应用户输入网络地址,到首屏内容渲染完成的时间。 一般是首屏中的图片加载完毕的时候,我们认为是首屏结束的时间点。
- 完全加载时间:DOM Tree 构建完成后,开始加载网页资源,资源完全加载完成后,从加载开始到此为网页的完全加载时间。
- 可交互时间 (TTI):用户第一次可以和界面进行交互的时间
- 慢会话 Long Tasks:RAIL有在100毫秒内相应用户输入的要求。如果响应超过这个时间就是慢会话
如何采集指标数据
PerformanceTiming中有许多指标,选取几个比较常用的。
- PerformanceTiming.responseStart:返回浏览器从服务器收到(或从本地缓存读取)第一个字节时的Unix毫秒时间戳。这个可以用来反映服务器或者是CDN响应的指标。
- PerformanceTiming.domInteractive:返回当前网页DOM结构结束解析、开始加载内嵌资源时间,用户可以开始输入交互的时间点
- PerformanceTiming.loadEventEnd: 整个页面加载结束的时间点
白屏时间的采集
可以用window.performance.getEntriesByType('paint')
返回结果就是FP和FCP
首屏时间的采集
首屏时间需要从两块去衡量,一块是图片的加载,一块是dom的渲染。
图片的加载时间可以使用window.performance.getEntriesByType('resource')
看一下返回的结果
需要判断initiatorType,取出responseEnd。
dom部分则用MutationObserver来监听dom变化。
另外考虑到是首屏,就需要配合getBoundingClientRect来判断元素是否在首屏内。
最后将两部分时间取较大值即可
拓展一下,如果你的首屏有其他资源会你也希望确认是否会大于图片的加载,可以参考
不同资源的加载时间的获取
TTI的采集
tti采集的库使用非常简单
import ttiPolyfill from './path/to/tti-polyfill.js';
ttiPolyfill.getFirstConsistentlyInteractive(opts).then((tti) => {
// Use `tti` value in some way.
});
长任务的收集
const subscribeBtn = document.querySelector('#subscribe');
subscribeBtn.addEventListener('click', (event) => {
// Event listener logic goes here...
const lag = performance.now() - event.timeStamp;
if (lag > 100) {
ga('send', 'event', {
eventCategory: 'Performance Metric'
eventAction: 'input-latency',
eventLabel: '#subscribe:click',
eventValue: Math.round(lag),
nonInteraction: true,
});
}
});
FPS
由于requestAnimationFrame会在每一帧渲染前被调用,所以fps的计算就依赖于他。
var frame = 0;
var allFrameCount = 0;
var lastTime = Date.now();
var lastFameTime = Date.now();
var loop = function () {
var now = Date.now();
var fs = (now - lastFameTime);
var fps = Math.round(1000 / fs);
lastFameTime = now;
allFrameCount++;
frame++;
if (now > 1000 + lastTime) {
//算出一秒左右的时间内总共渲染了多少帧
var fps = Math.round((frame * 1000) / (now - lastTime));
frame = 0;
lastTime = now;
};
window.requestAnimationFrame(loop);
}
loop();
参考资料
https://www.cnblogs.com/wmhua...
https://www.jianshu.com/p/456...
https://www.cnblogs.com/coco1...
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。