# 概述
性能优化对于前端是一个很重要的知识,网上文章有很多,但都比较零散,因此空闲时对性能优化做一个总结。
要优化一个网站的性能,首先需要学会如何衡量一个网站的性能。
如果不能衡量性能,就不能优化性能。性能衡量领域涉及的内容非常多,基础的有衡量指标、性能采集和上报方式、性能分析维度。
先只关注最基础的:性能衡量指标。
# 性能衡量指标(参考 w3c)
- onLoad
- 统计页面 onLoad 性能
- 统计方式: 页面 onload 事件触发事件 -
performance.timing.navigationStart
- 优点:统计简单方便,兼容性好
- 缺点:容易受打点请求和非首屏图片加载影响,使性能显得非常差
- DomReady
- 统计页面 domReady 性能
- 统计方式:页面 domContentLoad 事件触发时间点 -
performance.timing.navigationStart
- 优点:统计方便,兼容性好,相比 onLoad,不受页面后续图片和打点请求影响。如果是 ssr 页面 + jquery 绑定事件的方式,使用这个指标统计比较精准
- 缺点:统计到的性能可能偏好,尤其对于前端异步渲染的页面,domReady 后这类页面大概率还是白屏
- TTFB
- 统计页面(html 请求的)首字节时间
- 统计方式:
performance.timing.responseStart
-performance.timing.requestStart
- 优点:可以用来衡量后端(或 cdn)处理的时间,可以作为前端性能优化的起点指标。如果这个值比较大,就会压缩前端可优化的空间
- 缺点:是一个阶段指标,反应网络和后端处理速度。另外这个指标无法将网络和后端处理时间精确分开,不清楚到底是网络慢还是后端慢,需要结合其他指标(例如后端 RT)来进行细分
- FCP
- 首次内容绘制时间
- 统计方式:
performance.getEntriesByType('paint')
- 优点:能反应首次内容(文本、图片、svg)绘制,浏览器级别支持的 api,比较精准
- 缺点:浏览器兼容性,近反应首次有内容绘制,不能反应页面重要内容绘制时间
- LCP
- 最大内容绘制(LCP)指标会根据页面首次开始加载的时间点来报告可视区域内可见的最大图像或文本快完成渲染的相对时间
- 统计方式:要在 javascript 中测量 LCP,可以使用最大内容绘制 API
- 优点:chrome 推荐的性能指标,参与 lighthouse 网站评分权重,比较接近用户真实体感,在社区内与其他网站对比性能时,可作为权威
- 缺点:浏览器兼容性,部分动画或者一些页面元素发生替换时,统计不准确
- UC T2
- uc 浏览器内核提供的性能指标,用来统计页面首屏元素完整展示的时间
- 统计方式:uc 内核实现
- 优点:能反应首屏页面加载完成的速度
- 缺点:ios 不支持
- FPS / 卡帧率
- 根据页面每帧耗时,评估页面在渲染过程中是否出现卡顿
- 统计方式:在页面进入可交互状态后,使用 requestAnimationFrame 统计帧间隔时间,找出时长超过一定阈值的帧数量,统计得到画面卡顿次数
- 优点:相比于打开性能,能评估用户的交互性能,反应在使用页面过程中是否出现了卡顿
- 缺点:实现成本高,requestAnimationFrame 持续统计可能会对性能造成影响,统计的总时长和帧时长阈值的设置不同,对指标影响较大
- 自定义可交互
- 在 react 或 rax 等框架的 render 完成后,统计性能时间
- 统计方式:setState 回调、有⾸屏渲染所需要的数据那次 useEffect hook(可结合 requestAnimationFrame 更精准的统计)
- 优点:在 ssr 情况下,可反应页⾯可交互时间,⽽不只是元素渲染出来的时间
- 缺点:实现成本⾼,需要每个页⾯判断什么是⾸屏需要的数据
- Element Timing
- 页⾯开发者⾃由指定某个元素为⾸屏核⼼内容
- 统计方式:Element Timing API
- 优点:能根据业务情况,精准反应页⾯核⼼元素出现的时间;能对不同页⾯灵活设置不同的⾸屏元素;使⽤浏览器 API ,⽐⾃定义统计精准
- 缺点:实现成本⾼;横向对⽐其他页⾯没有权威性;API 兼容性问题;不能反应可交互时间
以上各性能指标的特性评估对比如下:
# 常用性能采集和上报调研
- APM(我司内部采用的方式)
- 暂不支持自定义上报
- 不支持性能告警
- iTrace(专属钉附带)
- 不支持告警
- 支持已有的部分性能指标上报
- Arms(阿里云收费,或可替代我司内部 APM)
- 支持自定义性能上报
- 支持告警配置