监控的指标:

google开发者提出了一种RAIL模型来衡量应用性能。

  1. Response:响应用户输入,
  2. Animation:动画或者滚动需在10ms内产生下一帧,
  3. Ilde:最大化空闲时间,
  4. Load:页面加载时长不超过5秒。

Animation,Idle,Load,分别代码web应用生命周期的四个不同方面。

  1. 以用户为中心,最终目标是不是让你的网站在任何特定设备上都能运行很快,而是让用户满意,
  2. 立即响应用户,在100毫秒以内确认用户输入,
  3. 设置动画或滚动时,在10毫秒以内生成帧,
  4. 最大程度增加主线程的空闲时间,
  5. 持续吸引用户,在1000号秒以内呈现交互内容。

我们可转化为三个方面来看:响应速度,页面稳定性,外部服务调用。

  1. 响应速度:页面初始访问速度 + 交互响应速度,
  2. 页面稳定性:页面出错率,
  3. 外部服务调用:网络请求访问速度。

页面访问速度:白屏,首屏时间,可交互时间。

  1. performance的The Paint Timing API: window.performance.getEntriesByType(“paint”);
  1. first paint(FP):首次渲染,
  2. first contentful paint(FCP):首次有内容的渲染。
  3. 这两个指标浏览器已经标准化了,从performance的The Paint Timing API可以获取到,一般来说两个时间想爱你沟通那个,但也有情况下两者不同。
  1. 假设当一个网页的DOM结构发生剧烈的变化的时候,就是这个网页主要内容出现的时候,那么在这样的一个时间点上,就是首次有意义的渲染
  1. First meaingFul paint: 首次有意义的渲染,
  2. hero element timing: 页面关键元素。
  1. Time to interactive:可交互时间。

Performace分析

performance属性

浏览器提供的performace API,这也是性能监控数据的主要来源,performace提供高精度的时间戳,精度可达纳秒级别,且不会随操作系统时间设置的影响。目前主流浏览器都支持。

  1. window.performance.navigation: 页面加载还是刷新,发生了多少次重定向,
  2. window.performance.timing: 页面加载的各阶段时长,
  3. window.performance.memory:基本内存使用情况,Chrome添加的一个非标准扩展。
  4. window.performance.timeorigin:性能测量开始时的时间高精度时间戳。

使用performace计算

performance.getEntriesByType(“navigation”);

  1. 重定向次数:performance.navigation.redirectCount,
  2. 重定向耗时: redirectEnd - redirectStart,
  3. DNS 解析耗时: domainLookupEnd - domainLookupStart,
  4. TCP 连接耗时: connectEnd - connectStart,
  5. SSL 安全连接耗时: connectEnd - secureConnectionStart,
  6. 网络请求耗时 (TTFB): responseStart - requestStart,
  7. 数据传输耗时: responseEnd - responseStart,
  8. DOM 解析耗时: domInteractive - responseEnd,
  9. 资源加载耗时: loadEventStart - domContentLoadedEventEnd,
  10. 首包时间: responseStart - domainLookupStart,
  11. 白屏时间: responseEnd - fetchStart,
  12. 首次可交互时间: domInteractive - fetchStart,
  13. DOM Ready 时间: domContentLoadEventEnd - fetchStart,
  14. 页面完全加载时间: loadEventStart - fetchStart,
  15. 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。

  1. let p = window.performance.getEntries();
  2. 重定向次数:performance.navigation.redirectCount
  3. JS 资源数量:p.filter(ele => ele.initiatorType === “script”).length
  4. CSS 资源数量:p.filter(ele => ele.initiatorType === “css”).length
  5. AJAX 请求数量:p.filter(ele => ele.initiatorType === “xmlhttprequest”).length
  6. IMG 资源数量:p.filter(ele => ele.initiatorType === “img”).length
  7. 总资源数量: window.performance.getEntriesByType(“resource”).length

不重复的耗时时段区分:

  1. 重定向耗时: redirectEnd - redirectStart
  2. DNS 解析耗时: domainLookupEnd - domainLookupStart、
  3. TCP 连接耗时: connectEnd - connectStart
  4. SSL 安全连接耗时: connectEnd - secureConnectionStart
  5. 网络请求耗时 (TTFB): responseStart - requestStart
  6. HTML 下载耗时:responseEnd - responseStart
  7. DOM 解析耗时: domInteractive - responseEnd
  8. 资源加载耗时: loadEventStart - domContentLoadedEventEnd

其他组合分析:

  1. 白屏时间: domLoading - fetchStart
  2. 粗略首屏时间: loadEventEnd - fetchStart 或者 domInteractive - fetchStart
  3. DOM Ready 时间: domContentLoadEventEnd - fetchStart
  4. 页面完全加载时间: 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));