1、背景
如何查看一个网页的性能,它的指标有哪些?它的优化方案又有哪些?
2、网页的重要性能指标
测量工具
<script>
(function () {
var script = document.createElement('script');
script.src =
'https://unpkg.com/web-vitals@3/dist/web-vitals.attribution.iife.js';
script.onload = function () {
// When loading `web-vitals` using a classic script, all the public
// methods can be found on the `webVitals` global namespace.
webVitals.onCLS(console.log);
webVitals.onFID(console.log);
webVitals.onLCP(console.log);
};
document.head.appendChild(script);
})();
</script>
2.1、首次内容绘制FCP(1.8s)
测量页面从开始加载到页面内容的任何部分在屏幕上完成渲染的时间。
指标:1.8s以内
2.1.1、优化方法
最简单粗暴的方法,根据官方网页测量分析页面后,提供的建议进行优化。
但是大体上所有网站都可以根据以下策略进行优化
2.1.1.1、消除阻塞渲染的资源
阻塞渲染的资源有两种js与css,但是确定要不要消除,要看它们是不是关键资源。
使用goolge工具查看
- 对于未使用的代码百分比越高,则有可能不是关键资源
- 明确代码不会在首次加载中使用到的js与css资源。
消除阻塞渲染的js资源方法
- 为其标记async或defer
- 删除没用的js代码
消除阻塞渲染的css资源方法
- 分割css资源,通过媒体查询进行加载。
- 延迟非关键css
2.1.1.2、缩小css
使用webpack提供的插件
2.1.1.3、移除未使用的css
通过google工具查看是否存在未使用的代码。
2.1.1.4、预连接到所需的css资源
举例,添加preconnect
<link rel="preconnect" href="https://example.com">
2.1.1.5、预加载关键请求
举例:当你的app.js文件会即刻执行请求其他的b.js与b.css文件的时候,可以考虑先将这两种资源预加载。
<head>
...
<link rel="preload" href="b.css" as="style" />
<link rel="preload" href="b.js" as="script" />
...
</head>
2.1.1.6、避免巨大的网络负载
页面请求的总资源大小最好不超过1.6m。
降低总资源大小的方法
- 延迟不是首页加载所需的资源
- 图片采用webp
2.2、最大内容绘制LCP(2.5s)
测量页面从开始加载到最大文本块或图像元素在屏幕上完成渲染的时间。
指标:2.5s以内
2.2.1 优化方法
- 与FCP优化方法保持一致。
- img、svg中的image、video、background-image、块级文本都会影响LCP。
- 关于图像,采用webp以及压缩图像,如果图像在lcp中不重要,则考虑延迟加载。有钱的话采用cdn。
- 预加载重要资源,如果确定某个资源应该被优先获取,使用
<link rel="preload">
<link rel="preload" as="script" href="script.js" />
<link rel="preload" as="style" href="style.css" />
<link rel="preload" as="image" href="img.png" />
<link rel="preload" as="video" href="vid.webm" type="video/webm" />
<link rel="preload" href="font.woff2" as="font" type="font/woff2" crossorigin />
2.3、首次输入延迟FID(0.1s)
测量从用户第一次与您的网站交互(例如当他们单击链接、点按按钮或使用由 JavaScript 驱动的自定义控件)直到浏览器实际能够对交互做出响应所经过的时间。
指标:0.1s以内
2.4、可交互时间TTI(5s)
测量页面从开始加载到视觉上完成渲染、初始脚本(如果有的话)完成加载,并能够快速、可靠地响应用户输入所需的时间。
指标:5s以内
优化方法:
- 同fcp的优化方法一致
- 优化js的执行时间
- 缩小js文件
- 减少第三方代码的影响,只引入需要的代码
2.5、总阻塞时间TBT(0.3s)
测量 FCP 与 TTI 之间的总时间,这期间,主线程被阻塞的时间过长,无法作出输入响应
优化方法:同tti的优化方法一致
3、渲染流水线图解
3.1、加载阶段渲染流水线
加载阶段,是指从发出请求到渲染出完整页面的过程,影响到这个阶段的主要因素有网络和 JavaScript 脚本。
并非所有的资源都会阻塞页面的首次绘制,比如图片、音频、视频等文件就不会阻塞页面的首次渲染;而 JavaScript、首次请求的 HTML 资源文件、CSS 文件是会阻塞首次渲染的。
3.2、交互阶段的渲染流水线
交互阶段,主要是从页面加载完成到用户交互的整合过程,影响到这个阶段的主要因素是 JavaScript 脚本。
大部分情况下,生成一个新的帧都是由 JavaScript 通过修改 DOM 或者 CSSOM 来触发的。还有另外一部分帧是由 CSS 来触发的。
- 如果在计算样式阶段发现有布局信息的修改,那么就会触发
重排操作. - 如果在计算样式阶段没有发现有布局信息的修改,只是修改了颜色一类的信息,那么就不会涉及到布局相关的调整,所以可以跳过布局阶段,直接进入绘制阶段,这个过程叫
重绘。 - 通过 CSS 实现一些变形、渐变、动画等特效,这是由 CSS 触发的,并且是在合成线程上执行的,这个过程称为
合成。
优化方案:
- 减少脚本执行时间,一种是将一次执行的函数分解为多个任务,使得每次的执行时间不要过久。另一种是采用 Web Workers。
- 避免强制布局,导致增长当前函数的执行时间。尽量不要在修改 DOM 结构时再去查询一些dom的相关值。
- 合理利用css合成动画,因为动画都是在合成线程上执行的,不会影响到渲染线程。