MDN 对 Web 性能 的定义:Web 性能是用户对加载时间和运行时的直观体验,既包含网站从加载到可交互、可响应所消耗的时间,也包含页面在交互时的流畅度。例如动画加载是否顺畅、页面是否可以滚动、弹窗是否可以展现、按钮是否可以点击等,
Web 性能
主要分为以下几个部分:
- 减少网站负载时间
- 尽快使用网站
- 流畅性、交互性
- 感知性能
- 测量性能
测量性能
可通过网站 pageSpeed 输入需要检测的网址进行检测。这个工具分析了 LCP、FID、CLS 等等指标,还给出了加载较久的原因。
图片优化
1. 加载策略:懒加载
可使用懒加载,避免初始加载时要加载所有图像
2. 最优格式:
- svg: 更适合颜色较少且不太逼真的照片的图像,矢量图
- png: 适合徽标、插图、图表或图标
- 渐进式 jpeg:在图片未加载出来时会有一个低分辨率的图片版本,加载完成后换为清晰版。
- webp: 既适合用于图像又适合用于动图,但并非所有浏览器都支持,不支持渐进式显示。除具有 Big Sur 或更早版本的 macOS 桌面版 Safari 14 外,所有主流浏览器都支持它
- avif: 比 webp 更高效、高性能和免版税的图像,受 Chrome、Opera 和 Firefox 的支持。
3. 图片压缩:
svg 压缩工具:SVGOMG
jpeg、png 压缩工具:ImageOptim 在线
通用压缩工具:Squoosh,75% 的质量设置就能够得到优秀的结果
在线服务,你可以将其用作图像 CDN,它们将根据请求图像的设备或浏览器类型自动提供正确的图像格式:Cloudinary、 Image Engine
4. 正确尺寸:
- 为不同屏幕分辨率提供不同尺寸的照片
- 提前为图片设置好尺寸,避免图片加载完毕引起页面重排重绘
<picture>
<source media="(max-width: 799px)" srcset="narrow-banner-480w.jpg" />
<source media="(min-width: 800px)" srcset="wide-banner-800w.jpg" />
// 若浏览器不支持 picture,则显示下面的 img
<img src="large-banner-800w.jpg" alt="茂密森林景观" />
</picture>
// img 的 srcset 和 sizes 设计的初衷是为不同尺寸显示不同分辨率的同一图案
// 而 picture、source 的设计是为了对于不同屏幕显示不同的图案,例如小屏幕显示紧凑版的图案,大屏幕显示分散版的图案
// 两个的设计初衷不同,常常用来配合使用来兼顾功能需求、代码维护和浏览器兼容性等多方面因素
<img
srcset="product-small.jpg 480w, product-medium.jpg 800w, product-large.jpg 1200w"
sizes="(max-width: 480px) 480px, (max-width: 800px) 800px, 1200px"
src="product-medium.jpg"
alt="A beautiful product"
/>
5. 控制下载图像的优先级:
将最重要的图片优先展示给用户
- <img> 的 src 的加载优先级高于 css 里 background-image 图片的优先级
- <img> 的 fetchPriority 属性,支持设置图像加载的优先级
视频优化
1. 压缩视频
压缩视频软件通常比较两个临近帧,删除临近帧之间的相同细节,来达到减少视频体积的目的。
对于静音视频,可以在导出视频的时候将音频移除,这样可以减少20%的带宽。
压缩工具:FFmpeg
2. 视频尺寸
不同分辨率的屏幕,显示不同大小的视频。
<video controls>
<source src="video/smaller.mp4" type="video/mp4" media="(min-width: 400px)" />
<source src="video/smaller.webm" type="video/webm" />
<source src="video/larger.mp4" type="video/mp4" media="(min-width: 800px)" />
<source
src="video/larger.webm"
type="video/webm"
media="(min-width: 800px)" />
</video>
3. 优化<source>顺序
<source> 在 <video> 标签中是用于指定视频来源的元素,一个 video 标签可包含多个 source 标签,以支持为不同浏览器提供合适的视频格式。
在设置 source 顺序时,可以将视频体积较小的放在前面。
4. 预加载、延迟加载视频
使用 <video> 的 preload 属性
preload:
none: 表示不应该预加载视频,对于播放量较少的视频可采用。metadata: 会下载视频的初始片段,可能会在页面加载时下载视频的 3%,建议仅当用户观看视频的可能性相当高或视频较小时才使用该方法。auto: 表示可以下载整个视频文件,只有播放量较高的视频适合这样做,否则这样会浪费大量的带宽。
5. 流媒体
为了以最快的速度播放,请从最低质量的流开始。对于较长的视频,您可以考虑在开始时使用“中等质量”流,以便在启动时提供清晰的视频。
JS 优化
1. 预加载重要的 js 文件
预加载重要的 js 文件,在浏览器空闲的时候提前加载文件,将其缓存起来备用。当页面后续真正需要使用该 js 代码时,由于已经提前下载好了,就可以快速地从缓存中提取并执行,减少了等待下载的时间,从整体上加快了页面的响应速度。
<head>
...
<!-- 预加载 JavaScript 文件 -->
<link rel="preload" href="important-js.js" as="script" />
<!-- 预加载 JavaScript 模块(包含文件内引入的其他js文件) -->
<link rel="modulepreload" href="important-module.js" />
...
</head>
2. 延迟加载不重要的 js 文件
尽量推迟解析和执行非关键 JavaScript 的时间,直到它真正需要时再加载。提前加载它会不必要地阻塞渲染。
<head>
...
<script async src="main.js"></script>
...
</head>
也可以使用 import 来动态引入模块。
3. 分解长任务
将长函数拆分为多个短函数,并适时使用 yield 或其他异步方式,使代码让步给主线程。
4. 处理 js 动画
去除非必要的动画,对于关键动画尽量选择 css 动画。
5. 更高效的编码
- 减少 dom 操作
- 批量对 dom 进行更改
- 减少循环
- 及时清除监听器
CSS 优化
1. 优化渲染
- 删除不必要的样式
- 拆分 css
<!-- 加载和解析 styles.css 会阻塞渲染 -->
<link rel="stylesheet" href="styles.css" />
<!-- 加载和解析 print.css 不会阻塞渲染 -->
<link rel="stylesheet" href="print.css" media="print" />
<!-- 在大屏幕上,加载和解析 mobile.css 不会阻塞渲染 -->
<link
rel="stylesheet"
href="mobile.css"
media="screen and (max-width: 480px)" />
- 压缩 css
- 删除不必要的长选择器,选用短的选择器代替
- 使用 css 精灵图
- 预加载重要资源
<link rel="preload" href="style.css" as="style" />
<link
rel="preload"
href="ComicSans.woff2"
as="font"
type="font/woff2"
crossorigin
/>
2. 处理动画
- 避免重排重绘
- 使用 will-change 属性,向浏览器提示元素预期的变化方式
.element {
will-change: opacity, transform;
}
3. 使用 preload 预加载字体资源
- 使用
rel="preload"来提前加载重要的字体 - 使用
rel="preconnect"与字体提供方建立早期连接。有关详细信息,请参阅预连接到关键的第三方源。 - 使用 CSS 字体加载 API 通过 JavaScript 自定义字体加载行为。
<link
rel="preload"
href="OpenSans-Regular-webfont.woff2"
as="font"
type="font/woff2"
crossorigin
/>