1 前端性能监控的两种方法
前端性能监控主要分为两种方式,一种叫做合成监控(Synthetic Monitoring,SYN),另一种是真实用户监控(Real User Monitoring,RUM)。
合成监控
就是在一个模拟场景里,去提交一个需要做性能审计的页面,通过一系列的工具、规则去运行你的页面,提取一些性能指标,得出一个审计报告。
工具如 YSlow 、webpagetest、阿里测、谷歌Lighthouse
以 Lighthouse 为例,提供命令行或安装谷歌插件
以A9 为例
我们会看到一个生成的性能报告,从这个性能报告里我们可以看到,Lighthouse 生成的不仅仅是一些性能相关的数据,甚至包括 PWA,然后一些 SEO,甚至一些前端工程化的最佳实践等等。
去掉ico图标后的检测
合成监控的优缺点
真实用户监控(RUM)
真实用户监控,就是用户在我们的页面上访问,访问之后就会产生各种各样的性能指标,我们在用户访问结束的时候,把这些性能指标上传到我们的日志服务器上,进行数据的提取清洗加工,最后在我们的监控平台上进行展示的一个过程。
优缺点
合成监控 vs 真实用户监控
真实用户性能数据采集方案
在真实用户性能数据采集时,要关注四个方面的东西
使用标准的 API;
定义合适的指标;
采集正确的数据;
上报关联的维度。
1 .使用标准的 API
HRtime 有两个特性,一个高精度,一个单调递增,保证了我们在提取性能指标的时候,不会受宿主环境的一些时间影响。
最佳实践是:采集性能数据时先抹平 Navigation Timing spec 差异,优先使用 PerformanceTimeline API。
2.定义合适的指标
页面加载时长
load 事件触发完成
优点:原生 API ,接受度高,感知明显(浏览器 Tab 停止 loading)。
缺点:无法准确反映页面加载性能,易受特殊情况影响。
首次渲染时长 First Paint
首次渲染:第一个非网页背景像素渲染
首次内容渲染时长 First Contentful Paint
首次内容渲染:第一个文本、图像、背景图片或非白色canvas/svg 渲染
首次渲染/首次内容渲染的时长非常接近
优点:
1. 原生API
2.衡量内容渲染时间,更贴近用户感知
缺点:
1.像素渲染不代表用户看见有效内容
2.大多数两个指标相差不大
首次有效渲染 First Meaningful Paint
页面结构发生剧烈改变(详细算法)
它的一个核心的想法是渲染并不一定代表着用户看到了主要内容,Load 也不一定代表用户看到主要内容,我们假设当一个网页的 DOM 结构发生剧烈的变化的时候,就是这个网页主要内容出现的时候,那么在这样的一个时间点上,就是用户看到主要内容的一个时间点。
优点:
1.相对校准的估算出内容渲染时间
2.贴近用户感知
缺点:
1.无原生API 支持
2.算法推导时DOM节点不含权重
开始渲染 Start Render
肉眼能够观察到页面内容发生变化的时间
优点:最直观、准确反映界面发生变化的指标
缺点:由于使用逐帧对比技术,无法在RUM场景使用
定义性能指标的一些方法
根据业务特性及性能监控方案选择最适合的性能指标,必要情况下可使用自定义性能点位。
3.采集正确的数据
规范的一个 RUM 性能模型
我们可以看到页面加载被定义成了很多个阶段
(1)fetchStart:发起获取当前文档的时间,我理解是浏览器收到页面发起请求的时间点。
(2)domainLookupStart:返回浏览器开始DNS查询的时间,如果此请求没有DNS查询过程,如长连接,资源Cache,或是本地资源,那么就返回fetchStart的值。
(3)domainLookupEnd: 返回浏览器结束DNS查询的时间,如果没有DNS查询同上。
(4)ConnectStart: 浏览器向服务器请求文档,开始建立连接的时间,如果此连接是一个长连接或者无需和服务器连接(使用缓存),则返回domainLookupEnd的值。
(5)ConnectEnd:浏览器向服务器请求文档,建立连接成功的时间。
(6)requestStart:开始请求文档时间(注意没有requestEnd)
(7)responseStart:浏览器开始接收第一个字节的时间,数据来自于服务器,缓存或本地。
(8)unloadEventStart:卸载一个文档开始的时间。
(9)unloadEventEnd:卸载一个文档结束的时间。
(10)responseEnd:浏览器接收最后一个字节数据的时间,连接被关闭的时间。
(12)domInterActive:浏览器把domcument.readyState设置为“interactive”的时间点,DOM树创建结束。
(13)domContentLoadedEventStart:文档发生DomContentLoaded的事件时间。
(14)domContentLoadedEventEnd:文档的DOMContentLoaded事件结束的时间。
(15)domComplete:浏览器把document.readyState设置为“complate”的时间点。
(16)loadEventStart:文档触发load事件的时间。
(17)loadEventEnd:文档触发load事件结束后的时间。
同域名tcp连接并发限制 ,单页面单域名限制6
浏览器正在分配缓存空间
当前有更高优先级请求正在处理
最佳实践:上报页面加载开始时间,以及后续各时间点相对增量,在数据端进行阶段清洗和异常处理,采集完合适的指标
4. 上报关联的维度
上图提到的点都是必须要采集的,但是在分析页面性能的时候,有很多相对专业的维度是会被大家忽略掉的,比如说当前页面是否可见,这个页面加载方式是怎么样的,它是直接打开,还是刷新打开,还是前进后退打开等等。就是通过后面的数据分析,我们会发现,不同的页面操作,页面打开方式都会对我们页面加载的性能会有影响,以及一些更复杂的,比如说是否启用 HTTP2、Service Worker 等等,这些数据我们都应该尽可能采集到,从而能够更好的去分析我们的页面性能。
准确分析性能数据及影响因素
意想不到的影响因素:
tab 可见状态
页面加载方式(打开,前进后退、刷新)
Service Worker(缓存)
.......
分析性能数据
计算方法,95分位数,平均数,10%截尾平均数
在实际分析性能指标的时候, 分析性能指标时建议关注百分位数 ,对性能的要求越高,使用越大的百分位数。
比如我们要承诺 99% 的用户都要小于 5 秒,我们看页面加载时长时候就应该看 99 分位数。如果我们现在精力不够,我们只能承诺 50% 的人页面加载时长小于 5 秒,实际上 50 分位数,就是中位数,就是 50% 的访问能够不小于这个时间打开这个页面。性能数据助力产品优化。