前段时间在工作中,需要判断模块bundle size缩减对页面的哪些性能产生了影响, 因此需要了解前端的性能指标如何定义的,以及前端有哪些性能分析工具, 于是顺便整理了一篇笔记, 以供前端小白对性能这块知识点做一个入门级的了解.
页面渲染
在了解性能指标和分析工具之前,有必要先弄清楚浏览器是如何渲染页面的.
Chrome 浏览器是多进程的, 每打开一个页面都会独立运行一个渲染器进程,从而保证如果其中一个页面无响应或崩溃不会影响其他页的活动.
● 浏览器进程(Browser Process):控制 chrome 应用程序,包括地址栏、书签、后退和前进按钮。还处理 Web 浏览器的不可见的特权部分,例如网络请求和文件访问。
● 渲染器进程(Renderer Process):控制页签中所有内容的显示, 渲染器进程包含GUI线程,主线程(js引擎线程),定时器触发线程,事件触发线程,异步http请求线程,合成线程,io线程
● 插件进程(Plugin Process):控制网站使用的任何插件,例如 flash。
● 图形处理器进程(GPU Process):独立于其他进程处理 GPU 任务。
渲染器进程的核心工作是将 HTML、CSS 和 JavaScript 转换为用户可以与之交互的网页,主要步骤如下:
- DOM 解析(Parsing) 渲染进程解析接收到的HTML数据并转化为DOM对象。
- 样式计算(Style calculation)主线程根据 CSS 样式选择器计算出的每个DOM元素应具备的具体样式。
- 布局(Layout)
布局过程中主线程会遍历构建的DOM树,根据DOM节点的计算样式计算出一个布局树(layout tree)布局树上每个节点会有它在页面上的x,y坐标以及盒子大小(bounding box sizes)的具体信息。布局树与先前构建的DOM树差不多,不同的是只有那些可见的节点。 - 分层(Dividing into layers)
分层的作用确定哪些元素需要放置在哪一图层,此过程主线程会遍历布局树来创建一棵层次树 - 绘制 (Paint)
有了 DOM、样式和布局信息仍不足以呈现页面。比如某些元素设置了z-index,仅按照 HTML 元素的顺序会导致渲染的结果不正确,所以还需要知道绘制的顺序。主线程会遍历之前的布局树(layout tree)来生成一系列的绘画记录(paint records),从而得到了绘制的顺序。 - 合成(Compositing)
合成是一种将页面分成若干层,分别对它们进行光栅化,然后在一个单独的线程 —合成线程(compositor thread)里合成为一个页面的技术。当用户滚动页面时,由于页面各个层都已经被光栅化了,浏览器需要做的只是合成一个新的帧来展示滚动后的效果
● note:
渲染过程中,如果遇到
主流浏览器每16.6ms刷新一次。每次需要完成如下工作
JS脚本执行 ----- 样式布局 ----- 样式绘制
当JS执行时间过长,超出了16.6ms,这次刷新就没有时间执行样式布局和样式绘制了,因此就会造成页面掉帧,造成卡顿。
Chrome DevTools Performance
在了解了以上渲染知识点可以帮助我们更好的理解Performance面板上的一些指标
● 控制面板(红色区域):控制性能分析相关功能的配置。
● 概览面板(蓝色区域):主要性能项目的图形化预览。可选择录制的某一个片段,默认为完整的录制片段。
● 视图面板(绿色区域):展示概览面板中选择的片段的其他指标数据。点击此面板中的内容可进行选择。
● 详情面板(黄色区域):展示视图面板中选择内容的详情。其中 Summary 选项卡为点选内容的数据总览,不同的点击项目展示的条目有所区别。而 Bottom-up、Call tree、Event log 选项卡主要与主线程活动相关,会在【Main】中做详细介绍。
控制面板
主要使用的按钮功能解释依次为:
● Record: 开始/停止记录页面运行时性能,再次点击结束记录并生成分析报告。
● Start profiling and load page: 点击后会重新加载页面并且声称记录, 需要产生分析报告必须点这个按钮
● Clear: 清空所有录制的分析内容。
● Load profile:上传之前保存的分析报告。
● Save profile:将当前记录的分析内容以 JSON 文件形式保存。每次记录都会生成一个性能分析报告可供下载;也可截取记录中的某段内容生成分析报告进行保存。
● Screenshots:是否启用屏幕截图 。启用后将会在录制时捕获每一帧的屏幕截图。可以通过这个选项查看页面是否支持ssr.
概览面板
GPU
CPU 资源使用情况,通常主要是 JavaScript(黄色)和css(紫色)。CPU 中面积图如果充满色彩就表示该时间段 CPU 已达到极限。当看到 CPU 长时间处于最大状态时就是需要寻找减少 CPU 工作量方法的提示。
视图面板
Network
资源网络请求的瀑布流。不同的颜色用于区分不同的资源类型(HTML、JS、Image等),鼠标悬浮可查看资源请求总耗时和优先级(Highest、High、medium、Low、Lowest)。鼠标点击某个资源请求可以在 Summary 选项卡中查看更详细的信息。
每个资源请求的图形中都存在一左侧线段、浅色矩形、深色矩形、右侧线段:
● 左侧线段:Request Sent 之前所有时间花费(Queueing ~ Proxy negotiation,后有详见👇🏻)。
● 浅色矩形:Request Sent + Waiting (TTFB)。从请求发出到浏览器接收到服务端响应的第一个字节花费的时间。
● 深色矩形:Content Download,内容下载耗时。
● 右侧线段:等待主线程的时间花费。
Timings
记录页面加载期间的重要阶段事件及其触发时间点。
其中几个长方形框表示的是常见的几个前端性能指标, 其中, Google 在20年五月提出了网站用户体验的三大核心指标:LCP、FID、CLS。
Frist Contentful Paint(FCP)
○ 页面上第一个元素绘制的时间点,对应白屏时间,「第一个元素」指的是文本、图像(包括背景图像)、svg元素或非白色的canvas元素。
Largest Contentful Paint(LCP)
最大内容绘制,指页面上最大的图片或文字绘制的时间点。该时间会随着页面渲染变化而变化, 因为页面中的最大元素在渲染过程中可能会发生改变,另外该指标会在用户第一次交互后停止记录
LCP可能被这四个因素影响:服务端响应时间, Javascript和CSS引起的渲染卡顿, 资源加载时间, 客户端渲染
Time to Interactive(TTI)
● 可流畅地响应用户交互的时间。
● 计算方式:
a. 从 FCP 开始
b. 找到第一个连续 5s 安静窗口(安静窗口指没有长任务且不超过两个 Get 请求)
c. 从安静窗口反推,找到最后一个长任务
d. 这个长任务结束的时间点就是 TTI
First Input Delay (FID)
FID 用户首次交互时间,值越低越好,记录在 FCP 和 TTI 之间用户首次与页面交互时响应的延迟, 就是看用户交互事件触发到页面响应中间耗时多少,如果其中有长任务发生的话那么势必会造成响应时间变长。推荐响应用户交互在 100ms 以内.
CLS
累计位移偏移,CLS(Cumulative Layout Shift),记录了页面上非预期的位移波动
文本移动了 25% 的屏幕高度距离(位移距离),位移前后影响了 75% 的屏幕高度面积(位移影响的面积),那么 CLS 为 0.25 * 0.75 = 0.1875。CLS 推荐值为低于 0.1,越低说明页面跳来跳去的情况就越少,用户体验越好
● 如何减少CLS
a. 给image,video或者其他具有长宽比的元素设置长宽值;
b. 尽量不要在已经渲染的内容前面插入内容;
c. 尽量选择transform animations属性去触发布局变动;
Total Blocking Time(TBT)
总阻塞时长,指的是 FCP 与 TTI 之间主线程被阻塞的总时长。
单个长任务阻塞时间 = 长任务时间(时间超过 50ms的任务) - 50ms,TBT 为这些阻塞时间的总和
Main
主线程活动。通过倒置的火焰图展示主线程上发生的活动,x 轴表示随时间的记录。y 轴代表调用堆栈。火焰图中顶部的事件会导致其下方的事件,火焰图顶层宽度越大就表示该活动可能存在性能问题。
火焰图顶部(根活动)由很多任务(Task)组成,使用灰色背景色区分。鼠标悬浮上去可以看到任务的总耗时。而超过50ms 的任务被称之为长任务,会被红色角标标记。因此 Main 视图中可查看导致掉帧的具体任务。
根活动是指那些导致浏览器做一些工作的活动,例如当单击一个页面时浏览器会触发一个 Event 作为根活动,这个 Event 可能会导致一系列的处理程序执行等。
详情面板
点击选择火焰图的某一活动或者选择某一时间段的活动,将在详情面板 Summary 选项卡中展示更多信息,结合详情面板的Call tree、Bottom-up、Event log 选项卡可以进行不同维度分析。
Summary
摘要,展示点选活动或某时间段所有活动的各阶段时间耗时
● Loading:网络请求与解析。
● Scripting: JS 执行时间。
● Rendering: 重排,主要包含样式计算、更新布局树、布局、分层等。
● Painting:重绘。更新分层、光栅化分层、合成等。
● System: 系统占用时间。
● Idle: 空闲时间。
● Total: 总计。
Call tree
调用树,通常用于查看选择的时间段中导致最多耗时的根活动。
下图中 Event 是一个根活动,嵌套结构表示表示调用栈,表示 Event 导致了 button.addEventListener,button.addEventListener 中执行了 b…
Bottom-up
自下而上,通常用于查看选择的时间段中直接花费时间最多的活动。
上面图例中可以看到几乎所有时间都花在了三个wait()的调用上。因此Bottom-up选项卡中的顶部活动是wait。
网站性能监测工具–lighthouse
Chrome扩展程序运行分析页面, 让开发人员根据生成的评估页面来进行网站优化和完善,提高用户体验。
(最好在无痕浏览器上生成分析报告)
性能优化测试的报告主要包括,Performance(页面性能)、Accessibility(可访性)、Best Practise(最佳实践)、SEO(搜索引擎优化)、Progressive Web App(渐进式应用)。我们点击其中的每一项都可以看到给出的具体优化建议. 你也可以在生成报告之前点击需要的类别来生成.
● 根据 Google 的说法,Lighthouse 会返回 0 到 100 之间的性能分数。100 是最高的分数,代表第 98 个百分位,即性能最佳的网站。50 分代表第 75 个百分位数。
Performance
这里我们只介绍和性能相关的Performance这一项, 我们以online landing page某个落地页为例,如下图:
● 性能测试结果会分成 Metrics,Diagnostic,Opportunities 三部分,但只有 Metrics 部分的指标项会对分数产生直接影响。
Metrics
● 影响评分的性能指标:First Contentful Paint, Time to Interactive, Speed Index, Largest Contentful Paint, 可以看到这个页面的最大内容绘制时间和流畅地响应用户交互的时间很长, 十分影响用户体验, 值得后续优化.
Opportunities
Lighthouse不仅能测试性能问题,还能告诉我们如何解决性能问题;Opportunities指的是优化机会,它提供了详细的建议和文档,来解释低分的原因,帮助我们具体进行实现和改进
展开随便一条可以看到给出的具体机会, 例如下图
可以对于第三方域, 建议我们使用preconnetc或者dns-prefetch提前与服务器建立链接
Diagonstics
Diagonstics指的是现在存在的问题, 为进一步改善性能的实验和调整给出了指导。
● lighthose 给出的建议是图片的高度宽度没有明确给定,导致渲染的时候一边计算一边渲染, 拖慢了渲染速度
note:
实上Lighthouse是一个性能测试工具,并不能完全代表用户的真实体验,当我们使用Lighthouse的时候,基于都是宿主机器的性能结果,虽然我们可以限制网速和CPU等等,但和现实还有有所差距。
参考文档:
https://segmentfault.com/a/1190000041753539
https://juejin.cn/post/7112544960934576136
https://juejin.cn/post/6844903971727884296
https://www.freecodecamp.org/chinese/news/front-end-engineering-performance-optimization/