- Published on
性能优化篇(五) : Preload
翻译至: Preload
此系列文章:
Preload
Preload(预加载) ( <link rel="preload">
) 是一种浏览器优化方式,允许更早地请求关键资源。
如果您愿意考虑如何手动排序关键资源的加载,那么它可以对 Core Web Vitals 中的加载性能和指标产生积极影响。也就是说,预加载并不是万能药,需要意识到一些权衡。
在优化交互时间或首次输入延迟等指标时,预加载对于加载交互所需的 JavaScript 包(或块)非常有用。请记住,使用预加载时需要非常小心,因为您需要避免延迟FCP(首次内容绘制)或LCP(最大内容绘制)所需的资源(例如图像或字体)为代价来提高交互性。
如果您正在尝试优化第一方 JavaScript 的加载,还可以考虑在文档中使用 <script defer>`` <head>
与 <body>
来帮助及早发现这些资源。
在单页应用程序中预加载
虽然预取是缓存可能很快请求的资源的好方法,但我们可以预加载需要立即使用的资源。也许是初始渲染中使用的某种字体,或者用户首屏立即看到的某些图像。
假设我们的 <EmojiPicker>
组件应该在初始渲染时立即可见。尽管它不应该包含在主包中,但它应该并行加载。就像 prefetch 一样,我们可以添加一个注释,让 Webpack 知道这个模块应该被预加载。
const EmojiPicker = import(/* webpackPreload: true */ "./EmojiPicker");
构建应用程序后,我们可以看到 <EmojiPicker>
组件 将被preload。
Asset Size Chunks Chunk Names
emoji-picker.bundle.js 1.49 KiB emoji-picker [emitted] emoji-picker
vendors~emoji-picker.bundle.js 171 KiB vendors~emoji-picker [emitted] vendors~emoji-picker
main.bundle.js 1.34 MiB main [emitted] main
Entrypoint main = main.bundle.js
(preload: vendors~emoji-picker.bundle.js emoji-picker.bundle.js)
实际输出在文档的 head 中显示为带有 rel="preload"
的 link 标记。
<link rel="prefetch" href="emoji-picker.bundle.js" as="script" />
<link rel="prefetch" href="vendors~emoji-picker.bundle.js" as="script" />
预加载的 <EmojiPicker>
可以与初始包并行加载。与 prefetch 不同的是,浏览器仍然可以决定是否拥有足够好的互联网连接和带宽来预取资源,而预加载则是无论如何都会被预加载。
资源将立即可供我们使用,而不必等到初始渲染后加载 <EmojiPicker>
由于我们通过更智能的排序来加载资源,因此初始加载时间可能会显着增加,
具体取决于您的用户设备和互联网连接。仅预加载初始渲染后约 1
秒内必须可见的资源。
Preload 和 async
如果您希望浏览器以高优先级下载脚本,但不阻塞解释器等待脚本完成,您可以利用下面的预加载 + 异步技巧。在此情况下,预加载可能会延迟其他资源的下载,但这是开发人员必须做出的权衡:
<link rel="preload" href="emoji-picker.js" as="script">
<script src="emoji-picker.js" async></script>
由于 Chrome 95+ 中对预加载的队列跳转行为进行了一些修复,该功能在更广泛的使用方面稍微安全一些。 Chrome preload的新建议:
把它放在HTTP标头中将优先于其他一切
一般来说,预加载将按照解释器获取任何 >= Medium 的内容的顺序加载,因此请小心将预加载放在 HTML 的开头。
字体预加载可能最好在头部末尾或正文开头
import
预加载应该在需要导入的脚本标记之后完成(因此首先加载/编译实际脚本)图像预加载的优先级较低,应相对于异步脚本和其他低/最低优先级标签进行排序