preload
preload: preload 将提升资源加载的先后。即预加载的作用
可被preload的资源:
audio
: 音频文件。document
: 一个将要被嵌入到<frame>
或<iframe>
内部的HTML文档。embed
: 一个将要被嵌入到<embed>
元素内部的资源。fetch
: 那些将要通过fetch和XHR请求来获取的资源,比如一个ArrayBuffer或JSON文件。font
: 字体文件。image
: 图片文件。object
: 一个将会被嵌入到<embed>
元素内的文件。script
: JavaScript文件。style
: 样式表。track
: WebVTT文件。worker
: 一个JavaScript的web worker或shared worker。video
: 视频文件。
Preload 与 prefetch 不同的地方就是它专注于当前的页面,并以高优先级加载资源,Prefetch 专注于下一个页面将要加载的资源并以低优先级加载。
preload 并不会阻塞 window 的 onload
事件。
使用 preload 指令的好处包括:
- 允许浏览器来设定资源加载的优先级因此可以允许前端开发者来优化指定资源的加载。
- 赋予浏览器决定资源类型的能力,因此它能分辨这个资源在以后是否可以重复利用。
- 浏览器可以通过指定
as
属性来决定这个请求是否符合 content security policy。 - 浏览器可以基于资源的类型(比如 image/webp)来发送适当的
accept
头。
preload 与 prefetch:
- preload 是告诉浏览器页面必定需要的资源,浏览器一定会加载这些资源;
- prefetch 是告诉浏览器页面可能需要的资源,浏览器不一定会加载这些资源。
prefetch 是预测会加载指定资源,如在我们的场景中,我们在页面加载后会初始化首屏组件,当用户滚动页面时,会拉取第二屏的组件,若能预测用户行为,则可以 prefetch 下一屏的组件。
preload 和 prefetch 混用的话,并不会复用资源,而是会重复加载。
preload 的功能听起来很像被 defer 的脚本,但是:
- defer 无法控制脚本执行的时机,是在
DOMContentLoaded
执行前触发 - defer 会阻塞
DOMContentLoaded
事件 - defer 会阻塞 onload 事件,preload 不会阻塞 onload 事件
- defer 的脚本下载的优先级是 low,preload 的脚本优先级是 high
<link rel="preload" href="image.png">
<link rel="preload" href="https://example.com/fonts/font.woff" as="font" crossorigin>
prefetch
Prefetch 是一个低优先级的资源提示,允许浏览器在后台(空闲时)获取将来可能用得到的资源,并且将他们存储在浏览器的缓存中。一旦一个页面加载完毕就会开始下载其他的资源,然后当用户点击了一个带有 prefetched 的l链接,它将可以立刻从缓存中加载内容
Link Prefetching
- HTML:
<link rel="prefetch" href="/uploads/images/pic.png">
- HTTP Header:
Link: </uploads/images/pic.png>; rel=prefetch
<link rel="prefetch" href="image.png">
DNS Prefetching
DNS prefetching 允许浏览器在用户浏览页面时在后台运行 DNS 的解析。如此一来,DNS 的解析在用户点击一个链接时已经完成,所以可以减少延迟。可以在一个 link 标签的属性中添加 rel="dns-prefetch'
来对指定的 URL 进行 DNS prefetching
<link rel="dns-prefetch" href="//fonts.googleapis.com">
<link rel="dns-prefetch" href="//www.google-analytics.com">
<link rel="dns-prefetch" href="//opensource.keycdn.com">
<link rel="dns-prefetch" href="//cdn.domain.com">
preconnect
preconnect 允许浏览器在一个 HTTP 请求正式发给服务器前预先执行一些操作,这包括 DNS 解析,TLS 协商,TCP 握手,这消除了往返延迟并为用户节省了时间。
<link href="https://cdn.domain.com" rel="preconnect" crossorigin>
扩展:
如果你想要浏览器在你访问某个域名前先执行 DNS 解析,那么你使用 preconnect 和 prefetch-dns 都是可以的,这将会节省关键渲染路径的时间。那么两个的区别?
Subresources
这种方式指定的预获取资源具有最高的优先级,在所有prefetch项之前进行:
<link rel="subresource" href="styles.css">
rel=subresource为当前页面提供了一种高优先级的资源预加载
prerender
<link rel="prerender" href="http://example.com">
这类似于在一个隐藏的 tab 页中打开了某个链接 – 将下载所有资源、创建 DOM 结构、完成页面布局、应用 CSS 样式和执行 JavaScript 脚本等。当用户真正访问该链接时,隐藏的页面就切换为可见,使页面看起来就是瞬间加载完成一样。