https://www.w3.org/TR/resource-hints/
https://www.w3.org/TR/preload/#use-cases
https://developer.mozilla.org/zh-CN/docs/Web/HTML/Preloading_content 这几个参考网址值得一看
dns-prefetch
DNS prefetch,即DNS预获取。前端优化中与DNS有关的两点:一个是减少DNS的请求次数,另一个是进行DNS预获取。
DNS预获取可以加快页面渲染速度,无需用户点击链接就能在后台解析,所以能减少用户的等待时间,提升用户体验;
默认情况下,浏览器会对当前页面中和当前域名(正在浏览网页的域名)不在同一个域的域名进行预获取,并且缓存结果,这就是隐式的DNS Prefetch。目前大多数浏览器已经支持此属性(IE9+);例如:
<!-- 开启DNS预获取 -->
<meta http-equiv="x-dns-prefetch-control" content="on">
<!-- 设置DNS预获取的域名 -->
<link rel="dns-prefetch" href="//g.alicdn.com" />
preload
浏览器会在遇到如下link标签时,立刻开始下载main.js(不阻塞 non-render-blocking ),并放在内存中,但不会执行其中的JS语句。只有当遇到script标签加载的也是main.js的时候,浏览器才会直接将预先加载的JS执行掉。
使用 as
来指定将要预加载的内容的类型,将使得浏览器能够:
as的取值如下:
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: 视频文件。
<!-- 跨域请求文件需要设置crossorigin, 如果是字体文件即使不跨域也需要设置 -->
<link rel="preload" href="fonts/cicle_fina-webfont.eot" as="font" type="application/vnd.ms-fontobject" crossorigin="anonymous">
preconnect
浏览器要建立一个连接,需要经过DNS查找,TCP三次握手和TLS协商(https需要),这些过程需要相当的耗时,所以preconnect,就是一项使浏览器预先建立一个连接(包含DNS查找,TCP三次握手和TLS协商),等真正需要加载资源的时候能直接请求;
<link rel="preconnect" href="//example.com">
<link rel="preconnect" href="//cdn.example.com" crossorigin>
浏览器会进行以下步骤:
* 解释href的属性值,如果是合法的URL,然后继续判断URL的协议是否是http或者https否则就结束处理
* 如果当前页面host不同于href属性中的host,crossorigin其实被设置为anonymous(就是不带cookie了),如果希望带上cookie等信息可以加上crossorign属性,corssorign就等同于设置为use-credentials
prefetch
设置此值能让浏览器预加载一个资源(html,js,css或图片),可以让用户跳转到其他页面时,响应速度更快。例如:
<link rel="prefetch" href="//example.com/next-page.html" as="html" crossorigin="use-credentials">
<link rel="prefetch" href="/library.js" as="script">
注意: 虽然是预加载了,但是页面不会解析或者JS是不会直接执行的。
prerender
而prerender不仅会加载资源,还会解执行页面,进行预渲染,但是这都是根据浏览器自身进行判断。
浏览器可能会
- 分配少量资源对页面进行预渲染
- 挂起部分请求直至页面可见时
- 可能会放弃预渲染,如果消耗资源过多等等情况。。。
<link rel="prerender" href="//example.com/next-page.html">
prefetch 与 preload区别
Both prefetch
and preload
declare a resource and its fetch properties, but differ in how and when the resource is fetched by the user agent: prefetch
is an optional and low-priority fetch for a resource that might be used by a subsequent navigation; preload
is a mandatory and high-priority fetch for a resource that is necessary for the current navigation. Developers should use each one accordingly to minimize resource contention and optimize load performance.
资源正在被预载时点击了某个链接会发生什么?
当用户点击一个连接,或开始任何形式的页面加载时,prefetch预取操作将被停止且任何预取提示将被丢弃。如果一个预取文档只下载了一部分,那么这部分文档将被保存在缓存中,供服务端发送一个 "Accept-Ranges: bytes" 的返回头。这个返回头通常是由网络服务器在返回静态内容时生成的。当用户真正访问这个已经(部分)预载过的文档时,该文档的剩余部分将被通过一个 HTTP byte-range 的请求获取。
如果后台正在进行下载任务会发生什么?预取会争夺带宽吗?
视情况而定。如果你正在使用 Mozilla 下载某些东西,预取将被推迟到下载结束。例如,如果你尝试加载书签组(将会开启多个浏览器标签),任何由书签组某页面发出的预取请求将被延迟到所有标签加载完毕时进行。如果你正在使用其他依赖网络的应用程序,那么 Mozilla 中的预取可能会与它们竞争带宽。这个问题我们希望将来能够借助操作系统服务去检测网络空闲时间来解决。