# 资源预加载
只是预加载,加载完成后不会执行
preload
:对于当前页面很有必要的资源使用 (关键的脚本、字体、主要图片)
prefetch
:对于可能在将来的页面中使用的资源使用
- 从一个页面跳转到另一个页面
prefetch
的请求不会中断 - 至少会缓存 5 分钟
# 缓存行为
Chrome
有四种缓存:
HTTP
缓存- 内存缓存
Service Worker
缓存Push
缓存
preload
和 prefetch
都被存储在 HTTP
缓存中。
- 当一个资源被
preload
或者prefetch
获取后,它可以从HTTP
缓存移动至渲染器的内存缓存中。 - 如果资源可以被缓存(比如说存在有效的
cache-control
和max-age
),它被存储在HTTP
缓存中可以被现在或将来的任务使用,如果资源不能被缓存在HTTP
缓存中,作为代替,它被放在内存缓存中直到被使用。
# 优先级

preload
使用 as
属性加载的资源将会获得与资源 type
属性所拥有的相同的优先级。比如说,preload as="style"
将会获得比 as="script"
更高的优先级。这些资源同样会受内容安全策略的影响(比如说,脚本会受到其 src
属性的影响)。
不带 as
属性的 preload
的优先级将会等同于异步请求。
# 问题
- 没有用到的
preload
资源在Chrome
的Console
里会在onload
3s 后发生警告
需要明确 preload
是一定会用到的资源,否则相当于浪费了流量
- 错误使用可能导致二次获取
prefetch
不要作为preload
的后备,它们适用于不同场景- 明确
as
属性使用 - 添加
crossorigin
属性
- 不要预加载所有文件
preload
关键文件(可能阻塞加载的,例如图片、样式、字体、媒体资源)
# 应用
# 检测是否支持
const preloadSupported = () => {
const link = document.createElement("link");
const relList = link.relList;
if (!relList || !relList.supports) return false;
return relList.supports("preload");
};
1
2
3
4
5
6
2
3
4
5
6
# 脚本化预加载
在这里创建一个 HTMLLinkElement
实例,然后将他们附加到 DOM
上:
// 这意味着浏览器将预加载这个JavaScript文件,但并不实际执行它。
var preloadLink = document.createElement("link");
preloadLink.href = "myscript.js";
preloadLink.rel = "preload";
preloadLink.as = "script";
document.head.appendChild(preloadLink);
1
2
3
4
5
6
2
3
4
5
6
如果要对其加以执行,在需要的时候,你可以执行:
var preloadedScript = document.createElement("script");
preloadedScript.src = "myscript.js";
document.body.appendChild(preloadedScript);
1
2
3
2
3
当你需要预加载一个脚本,但需要推迟到需要的时候才令其执行时,这种方式会特别有用。
# 加载完成立即生效
<!-- css -->
<link rel="preload" href="style.css" onload="this.rel=stylesheet" />
<!-- script -->
<link
rel="preload"
as="script"
href="async_script.js"
onload="var script = document.createElement('script'); script.src = this.href; document.body.appendChild(script);"
/>
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10