【Web技术】861- 4000字带你了解 Web 前端监控
前言:为什么需要监控
web 的性能一定程度上影响了用户留存率,Google DoubleClick 研究表明:如果一个移动端页面加载时长超过 3 秒,用户就会放弃而离开。BBC 发现网页加载时长每增加 1 秒,用户就会流失 10%。
RAIL
模型来衡量应用性能,即:Response
、Animation
、Idle
、Load
,分别代表着 web 应用生命周期的四个不同方面。并指出最好的性能指标是:100ms 内响应用户输入;动画或者滚动需在 10ms 内产生下一帧;最大化空闲时间;页面加载时长不超过 5 秒。响应速度:页面初始访问速度 + 交互响应速度 页面稳定性:页面出错率 外部服务调用:网络请求访问速度
1.页面访问速度:白屏、首屏时间、可交互时间
1)first paint (FP) and first contentful paint (FCP)
这两个指标浏览器已经标准化了,从 performance 的
The Paint Timing API
可以获取到,一般来说两个时间相同,但也有情况下两者不同。我们假设当一个网页的 DOM 结构发生剧烈的变化的时候,就是这个网页主要内容出现的时候,那么在这样的一个时间点上,就是首次有意义的渲染。这个指标浏览器还没有规范,毕竟很难统一一个标准来定义网站的主体内容。
first meaningful paint
:https://docs.google.com/document/d/1BR94tJdZLsin5poeet0XoTW60M0SjvOJQttKT-JK8HI/view2.页面稳定性:页面出错情况
资源加载错误 JS 执行报错
3.外部服务调用
CGI 耗时 CGI 成功率 CDN 资源耗时 监控的分类?
合成监控
Lighthouse
、PageSpeed
、WebPageTest
、Pingdom
、PhantomJS
等。Lighthouse
是 google 一个开源的自动化工具,运行 Lighthouse
的方式有两种:一种是作为 Chrome 扩展程序运行;另一种作为命令行工具运行。Chrome 扩展程序提供了一个对用户更友好的界面,方便读取报告。通过命令行工具可以将 Lighthouse 集成到持续集成系统。合成监控方式的优缺点:
无侵入性。 简单快捷。缺点: 不是真实的用户访问情况,只是模拟的。 没法考虑到登录的情况,对于需要登录的页面就无法监控到。
真实用户监控
FrontJs
、oneapm
、Datadog
等。是真实用户访问情况。 可以观察历史性能趋势。 有一些额外的功能:报表推送、监控告警等等。缺点: 有侵入性,会一定程度上响应 web 性能。
performance 分析
基本属性
基本方法
performance
实体对象,通过 getEntriesByName
和 getEntriesByType
方法可对所有的 performance
实体对象 进行过滤,返回特定类型的实体。performance.getEntriesByName() performance.getEntriesByType() performance.mark() performance.clearMarks() performance.measure() performance.clearMeasures() performance.now() ...
提供的 API
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
performance.getEntriesByType("resource");
// 某类资源的加载时间,可测量图片、js、css、XHR
resourceListEntries.forEach(resource => {
if (resource.initiatorType == 'img') {
console.info(`Time taken to load ${resource.name}: `, resource.responseEnd - resource.startTime);
}
});
总结
let p = window.performance.getEntries();
performance.navigation.redirectCount
p.filter(ele => ele.initiatorType === "script").length
p.filter(ele => ele.initiatorType === "css").length
p.filter(ele => ele.initiatorType === "xmlhttprequest").length
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
const p = window.performance.getEntries();
let cssR = p.filter(ele => ele.initiatorType === "script");
Math.max(...cssR.map((ele) => ele.responseEnd)) - Math.min(...cssR.map((ele) => ele.startTime));
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));
如何监控?
保证数据的准确性 尽量不影响应用的性能
1.基本性能上报
performance navagation timing
中的所有点都上报,其余的上报内容可参考 performance 分析一节中截取部分上报。例如:白屏时间,JS 和 CSS 总数,以及加载总时长。2.首屏时间计算
performance.getEntries()
拿到的所有图片实体对象,根据图片的初始加载时间和加载完成时间去更新首屏渲染时间。MutationObserver
接口提供了监视对 DOM 树所做更改的能力,是 DOM3 Events 规范的一部分。3.异常上报
1)js error 监听 window.onerror 事件 2)promise reject 的异常 监听 unhandledrejection 事件
window.addEventListener("unhandledrejection", function (event) {
console.warn("WARNING: Unhandled promise rejection. Shame on you! Reason: "
+ event.reason);
});
3)资源加载失败 window.addEventListener('error') 4)网络请求失败 重写 window.XMLHttpRequest 和 window.fetch 捕获请求错误 5)iframe 异常 window.frames[0].onerror 6)window.console.error
4.CGI 上报
本文作者:liu, summerqy
本文链接:http://www.alloyteam.com/2020/01/14184/
回复“加群”与大佬们一起交流学习~
点击“阅读原文”查看 100+ 篇原创文章
评论