初步性能指标

162 阅读3分钟

最近项目中,需要对移动端的页面性能需要做个提升。在固定安卓环境下,对页面性能各个指标的统计,以此为基准,通过其他技术方案进行优化

image.png

由于performance.timing这个指标慢慢已经被遗弃了,需要使用新的指标performance.getEntriesByType('navigation')[0]performance.timingperformance.getEntriesByType('navigation')[0]两个时间统计会有点差异,后者统计的时间都是相对本次请求开始作为起始时间,这点比较重要。

1、PerformanceNavigationTiming

performance.getEntriesByType('navigation')[0]获取到的对象为 PerformanceNavigationTiming

常用属性含义
startTime返回0的记录
domContentLoadedEventEnd当前文档的DOMContentLoaded 事件完成后的时间,浏览器已完全加载 HTML,并构建了 DOM 树,但像 <img> 和样式表之类的外部资源可能尚未加载完成
domContentLoadedEventStart发生DOMContentLoaded之前的时间点
domInteractive前文档就绪状态设置为interactive
loadEventEnd等于当前文档的load加载事件完成的时间
loadEventStart等于当前文档的load加载事件前的时间
unloadEventEndunload事件结束事时间
unloadEventStartunload开始时间
fetchStart浏览器准备好使用 HTTP 请求获取文档

2、常用指标

字段计算方式(都是performance.getEntriesByType('navigation')[0]的属性值)解释
页面卸载时间unloadEventEnd - unloadEventStart前一个页面卸载,存在unload事件
重定向时间redirectEnd - redirectStart重定向次数过多,容易导致时间消耗过多
appCachedomainLookupStart - fetchStart缓存耗时
DNS查询domainLookupEnd - domainLookupStartDNS解析耗时
TCP握手connectEnd - connectStartTCP链接耗时
HTTP响应responseEnd - requestStartHTML下载时间
DOM解析domInteractive - responseEnd
资源加载loadEventStart - domContentLoadedEventEnd
白屏responseEnd - fetchStart
首屏domInteractive - fetchStart可交互,粗略计算
DOM ReadydomContentLoadedEventEnd - fetchStart
页面完全加载loadEventStart - fetchStart

用户指标

字段计算方式
FP首次绘制,是时间线上的第一个“时间点”,它代表浏览器第一次向屏幕传输像素的时间,也就是页面在屏幕上首次发生视觉变化的时间,performance.getEntriesByType('paint')[0]
FCP首次内容绘制,代表浏览器第一次向屏幕绘制 “内容”。注意:只有首次绘制文本、图片(包含背景图)、非白色的canvas或SVG时才被算作FCPperformance.getEntriesByType('paint')[1]

3、资源计算

performance.getEntries()获取各种请求资源所耗时间与数量

const rules =[]
const entries=window.performance.getEntries();
[{name:"JS 资源数量",value:"script"},{name:"CSS 资源数量",value:"css"},{name:"IMG 资源数量",value:"img"},{name:"AJAX 请求数量",value:"xmlhttprequest"},{name:"fetch 请求数量",value:"fetch"}].forEach(item=>{
   const currentEntries=entries.filter(ele => ele.initiatorType === item.value);
   if (currentEntries&&currentEntries.length){rules.push({target:item.name,count:currentEntries.length,start:Math.min(...currentEntries.map((ele)=>ele.startTime)),end:Math.max(...currentEntries.map((ele) => ele.responseEnd))});
 }
 });
console.table(rules);

4、耗时精准计算

performance.now() 返回页面初始化到调用该方法时的毫秒数 performance.now()Date.now()区别

  • 在于精度,performance.now()统计到微秒
  • 时间值,performance.now()是从页面初始化时间算起,而Date.now()是相对于1970年1月1日算起
  • Date.now()会受系统时间影响(可被人为手动调整),performance.now()是相对页面初始化时间,匀速递增

因为计算,游戏中sdk初始化,开始等时间就会比较精准

5、数据汇总时间点

一般可选择页面的unload时候触发,有时候可以灵活处理。 如果过早上报,有可能部分数据还未正常统计出来

const rules=[];
//...统计,埋点等
window.addEventListener("unload",()=>{
    //发送收集后的数据rules 
})

6、精准首屏时间计算

可以利用 MutationObserver 接口提供了监视对 DOM 树所做更改的能力,确认某些元素在我们已知会出现在首屏里,然后对其监视,一旦检测到变化,该时间点就是首屏时间。但是有个缺点,就是要确认那些元素会出现在首屏。

参考文章

web性能监控 FCP