preload预加载关键assets以提高加载速度

522 阅读3分钟

preload 预加载关键 assets 以提高加载速度

<link rel="preload">

打开网页时,浏览器会从服务器请求 HTML 文档,解析其内容,并为引用资源提交单独请求。作为开发人员,您知道页面需要的所有资源以及哪些资源最为重要。您可以使用这些知识提前请求关键资源,加快加载的过程。

预加载的工作原理

预加载最适合用于浏览器通常较晚发现的资源

13.webp

例如上图的Pacifico字体,是在样式表中通过@font-face规则定义的。浏览器只有在完成下载和解析样式表后才会加载这个字体文件。

当开发者认为某项资源更加重要时,通过预加载某个资源,可以使浏览器比正常发现它更早地获取该资源。

14.webp

上图即表示字体实现了预加载。

关键请求链代表着浏览器优先处理和获取的资源顺序。

可以通过在 HTML 文档的头部添加带有rel="preload"的标记来实现预加载资源:

<link rel="preload" as="script" href="***.js">

浏览器会缓存预加载的资源,以便在需要时立即可用。(它不会执行脚本或应用样式表。)

浏览器会根据情况执行诸如preconnectprefetch等资源提示。而另一方面,preload 对浏览器来说是强制性的。现代浏览器已经非常擅长对资源进行优先级排序。

PS:谨慎使用 preload 并且只预加载最关键的资源。

用例

预加载 CSS 中定义的资源

在浏览器下载并解析 CSS 文件之前,不会发现这些文件中使用的@font-face规则定义的字体或背景图像。预加载这些资源,可确保在下载 CSS 文件之前获取它们。

预加载 CSS 文件

如果使用了关键 CSS 方法,那么 CSS 将分成两部分。渲染首屏内容所需的关键 CSS 内联在文档的 <head> 中,非关键 CSS 通常使用 JavaScript 延迟加载。在加载非关键 CSS 之前等待 JavaScript 执行会导致用户滚动时呈现延迟,因此最好使用 <link rel="preload">更快地启动下载。

预加载 JavaScript 文件

由于浏览器不执行预加载的文件,因此预加载有助于将获取与执行分开,这可以改善 Time to Interactive 等指标。如果你拆分 JavaScript 包并仅预加载关键块,则预加载效果最佳。

如何实现 rel=preload

实现 preload 最简单的方法是在文档的 <head> 中添加一个<link> 标记:

<head><link rel="preload" as="script" href="***.js"></head>

as属性不能省略!提供 as 属性可帮助浏览器根据其类型来设置预获取资源的优先级,设置正确的标头,以及确定资源是否已存在于缓存中。此属性可接受的值包括: scriptstylefontimage 等等。

PS:省略 as 属性或使用了无效值,就相当于 XHR 请求,这时浏览器不知道它获取的内容,因此无法确定正确的优先级。它还可能导致某些资源(例如脚本)被获取两次。

某些类型的资源,例如字体,以匿名模式加载。对于这些资源,你必须设置 preloadcrossorigin 属性:

<link rel="preload" href="ComicSans.woff2" as="font" type="font/woff2" crossorigin>

对于字体文件,浏览器必须使用匿名模式来加载。

PS: 没有设置 crossorigin 属性的预加载的字体将被获取两次!

使用 webpack 预加载 JavaScript 模块

如果你使用了类似 webpack 这样的模块打包器,则需要检查它是否支持“预加载”标签的注入。

在 webpack4.6.0+的版本中,它通过在 import()中使用 magic comments 魔法注释来支持预加载:

import(_/* webpackPreload: true */_ "CriticalChunk")

如果是低于此版本的 webpack,那就用插件,例如preload-webpack-plugin

结论

为提高网页速度,请预加载浏览器来发现较晚的重要资源。但是预加载全部资源会适得其反!因此请谨慎使用 preload,并衡量它具体的作用。