preload
preload
是 <link>
标签 rel
属性的属性值,同时需要配合 as
属性使用。
as
指定将要预加载的内容的类型,使得浏览器能够:
- 更精确地优化资源加载优先级。
- 匹配未来的加载需求,在适当的情况下,重复利用同一资源。
- 为资源应用正确的内容安全策略。
- 为资源设置正确的 Accept 请求头。
看一下这个示例:
<link rel="preload" href="https://cdn.jsdelivr.net/npm/vue/dist/vue.js" as="script">
这种做法将把 <link>
标签塞入一个预加载器中。
这个预加载器在不阻塞页面 onload 事件的情况下,去加载资源。
我们可以通过以下两个示例来作一个对比:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
console.time('load')
</script>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/echarts/2.1.10/chart/bar.js"></script>
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
</head>
<body>
<script>
window.onload = () => {
console.timeEnd('load') // load: 1449.759033203125ms
}
</script>
</body>
</html>
上面这个示例从加载到触发 onload 事件需要大概 1400 ms 的时间。再看一下使用 preload 预加载的时间:
<link rel="preload" href="https://cdn.jsdelivr.net/npm/vue/dist/vue.js" as="script">
<link rel="preload" href="https://cdn.bootcdn.net/ajax/libs/echarts/2.1.10/chart/bar.js" as="script">
<link rel="preload" href="https://unpkg.com/element-ui/lib/index.js" as="script">
<link rel="preload" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css" as="style">
window.onload = () => {
console.timeEnd('load') // load: 10.8818359375ms
}
用 preload 来加载资源,只需要 10 ms 就触发了 onload 事件。
说明同样是下载文件,使用 preload 不会阻塞 onload 事件。
#prefetch
prefetch
和 preload
不同,使用 prefetch
属性指定的资源将在浏览器空闲时间下下载。
在资源的请求头如果发现有下面这个属性,就代表它是通过 prefetch
加载的:
purpose: prefetch
另外,空闲时间是如何确定、如何获取的,目前还没有相关 API。
#preload 和 defer 的区别
preload 和 defer 的相同点是异步下载。那它们的不同点是什么呢?
preload 下载的资源只有在遇到同样的 script 标签时,才会执行对应的脚本。例如下面预加载的 vue.js
:
<link rel="preload" as="script" href="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">
只有在遇到下面的标签时,才会执行加载的 vue.js
:
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
defer 则是异步下载资源,在所有元素解析完成后,触发 DOMContentLoaded 事件前执行。