监控的指标:
google开发者提出了一种RAIL模型来衡量应用性能。
- Response:响应用户输入,
- Animation:动画或者滚动需在10ms内产生下一帧,
- Ilde:最大化空闲时间,
- Load:页面加载时长不超过5秒。
Animation,Idle,Load,分别代码web应用生命周期的四个不同方面。
- 以用户为中心,最终目标是不是让你的网站在任何特定设备上都能运行很快,而是让用户满意,
- 立即响应用户,在100毫秒以内确认用户输入,
- 设置动画或滚动时,在10毫秒以内生成帧,
- 最大程度增加主线程的空闲时间,
- 持续吸引用户,在1000号秒以内呈现交互内容。
我们可转化为三个方面来看:响应速度,页面稳定性,外部服务调用。
- 响应速度:页面初始访问速度 + 交互响应速度,
- 页面稳定性:页面出错率,
- 外部服务调用:网络请求访问速度。
页面访问速度:白屏,首屏时间,可交互时间。
- performance的The Paint Timing API: window.performance.getEntriesByType(“paint”);
- first paint(FP):首次渲染,
- first contentful paint(FCP):首次有内容的渲染。
- 这两个指标浏览器已经标准化了,从performance的The Paint Timing API可以获取到,一般来说两个时间想爱你沟通那个,但也有情况下两者不同。
- 假设当一个网页的DOM结构发生剧烈的变化的时候,就是这个网页主要内容出现的时候,那么在这样的一个时间点上,就是首次有意义的渲染
- First meaingFul paint: 首次有意义的渲染,
- hero element timing: 页面关键元素。
- Time to interactive:可交互时间。
Performace分析
performance属性
浏览器提供的performace API,这也是性能监控数据的主要来源,performace提供高精度的时间戳,精度可达纳秒级别,且不会随操作系统时间设置的影响。目前主流浏览器都支持。
- window.performance.navigation: 页面加载还是刷新,发生了多少次重定向,
- window.performance.timing: 页面加载的各阶段时长,
- window.performance.memory:基本内存使用情况,Chrome添加的一个非标准扩展。
- window.performance.timeorigin:性能测量开始时的时间高精度时间戳。
使用performace计算
performance.getEntriesByType(“navigation”);
- 重定向次数:performance.navigation.redirectCount,
- 重定向耗时: redirectEnd - redirectStart,
- DNS 解析耗时: domainLookupEnd - domainLookupStart,
- TCP 连接耗时: connectEnd - connectStart,
- SSL 安全连接耗时: connectEnd - secureConnectionStart,
- 网络请求耗时 (TTFB): responseStart - requestStart,
- 数据传输耗时: responseEnd - responseStart,
- DOM 解析耗时: domInteractive - responseEnd,
- 资源加载耗时: loadEventStart - domContentLoadedEventEnd,
- 首包时间: responseStart - domainLookupStart,
- 白屏时间: responseEnd - fetchStart,
- 首次可交互时间: domInteractive - fetchStart,
- DOM Ready 时间: domContentLoadEventEnd - fetchStart,
- 页面完全加载时间: loadEventStart - fetchStart,
- http 头部大小: transferSize - encodedBodySize。
Resource Timing API
performance.getEntriesByType(“resource”);
/ 某类资源的加载时间,可测量图片、js、css、XHR
performance.getEntriesByType("resource").forEach(resource => {
if (resource.initiatorType == 'img') {
console.info(`Time taken to load ${resource.name}: `, resource.responseEnd - resource.startTime);
}
});
总结
基于 performance 我们可以测量如下几个方面:mark、measure、navigation、resource、paint、frame。
- let p = window.performance.getEntries();
- 重定向次数:performance.navigation.redirectCount
- JS 资源数量:p.filter(ele => ele.initiatorType === “script”).length
- CSS 资源数量:p.filter(ele => ele.initiatorType === “css”).length
- AJAX 请求数量:p.filter(ele => ele.initiatorType === “xmlhttprequest”).length
- IMG 资源数量:p.filter(ele => ele.initiatorType === “img”).length
- 总资源数量: window.performance.getEntriesByType(“resource”).length
不重复的耗时时段区分:
- 重定向耗时: redirectEnd - redirectStart
- DNS 解析耗时: domainLookupEnd - domainLookupStart、
- TCP 连接耗时: connectEnd - connectStart
- SSL 安全连接耗时: connectEnd - secureConnectionStart
- 网络请求耗时 (TTFB): responseStart - requestStart
- HTML 下载耗时:responseEnd - responseStart
- DOM 解析耗时: domInteractive - responseEnd
- 资源加载耗时: loadEventStart - domContentLoadedEventEnd
其他组合分析:
- 白屏时间: domLoading - fetchStart
- 粗略首屏时间: loadEventEnd - fetchStart 或者 domInteractive - fetchStart
- DOM Ready 时间: domContentLoadEventEnd - fetchStart
- 页面完全加载时间: loadEventStart - fetchStart
JS 总加载耗时:
const p = window.performance.getEntries();
let jsR = p.filter(ele => ele.initiatorType === "script");
Math.max(...cssR.map((ele) => ele.responseEnd)) - Math.min(...cssR.map((ele) => ele.startTime));
CSS总加载耗时:
const p = window.performance.getEntries();
let cssR = p.filter(ele => ele.initiatorType === "css");
Math.max(...cssR.map((ele) => ele.responseEnd)) - Math.min(...cssR.map((ele) => ele.startTime));