翻译自:Medium - Resource Hintsjavascript
Resouce Hints 让咱们能够帮助浏览器寻找到它将要用到的资源,而后提早下载它们以期得到更佳的性能。html
对于现代化的网站,速度优化须要的再也不仅仅是最小化初始下载大小和 critical rendering path ,咱们还能够经过尽早地解析并预取资源来优化资源的加载。html5
“预取”只是在一个资源被须要以前就开始下载的行为,以期来提供快速、即时的体验。java
Dns-prefetch 是在浏览器请求资源以前,开启资源所在的每一个域的 DNS 解析的过程,目的是当浏览器真正地请求资源时节省 DNS 解析时间。web
你能够把 DNS 解析理解成浏览器为了将
domain/hostname
转化成一个访问资源所需 ip 地址的必通过程(这个过程就是把对用户友好的 url,好比 www.medium.com/,转成 http://80.72.139.1.0)。浏览器
经过检查 amazon.com 站点的源码,你会在其主页的顶部找到如下代码:缓存
<link rel='dns-prefetch' href='//g-ecx.images-amazon.com'>
<link rel='dns-prefetch' href='//completion.amazon.com'>
复制代码
Amazon.com 使用 DNS-prefetch 来解析多个域名,从中获取不一样的资源,如图像、JS 和 CSS 文件。当浏览器遇到这些 URLs 时,它首先检查缓存,若是没有命中缓存,则向 DNS 服务器发送请求来解析出域名相应的 IP 地址。这些请求在后台处理并不会阻塞页面的渲染。服务器
DNS 查询的成本是很低的——它们只经过网络发送几百个字节,所以没有太大的风险。网络
你能够在这个网站检查浏览器是否支持 DNS-prefetch:caniuse.com/#feat=link-…架构
若是你使用的是 HTTPS,它能够完成与某个域创建链接的全部工做,包括 DNS 查找、TCP 握手和TSL 协商。
preconnect 能够经过 提早执行这项工做来屏蔽高延迟链接 以及削减启动请求的宝贵时间:
<link rel="preconnect" href="//example.com">
复制代码
你能够在这个网站检查浏览器是否支持此功能:caniuse.com/#feat=link-…
摘自 MDN:
Link prefetching 是一种浏览器机制,这种机制利用浏览器的空闲时间来下载或者预取用户可能在不久的未来访问的文档。一个 web 页面向浏览器提供一组 prefetching hints,而后浏览器加载完页面后,开始静默地预取指定文档并将其存储在缓存中。当用户访问其中一个预取文档时,能够快速地将其从浏览器的缓存中提取出来。
所以,这意味着 prefetch 用于获取和缓存资源,这些资源将在用户可能访问的后续路由中使用。
prefetch 能够用于一个带有 prefetch
和 url
属性的 link
标签:
<link rel="prefetch" href="//example.com/next-page.html" as="html" crossorigin="use-credentials">
<link rel="prefetch" href="/library.js" as="script">
复制代码
as
属性是可选的,它用来帮助浏览器的 preloader 优化预取过程。
crossorigin
属性也是可选的,它容许你为给定的资源指定跨源策略。
只有可以被缓存的元素应该使用预取功能。
你能够在这个网站检查浏览器是否支持此功能:caniuse.com/#feat=link-…
preload 相似于 prefetch,区别在于 prefetch 用于发起对后续路由中将要使用的资源的请求,而 preload 则用于预取同一个页面中将要用到的资源。
<link rel="preload" href="/library.js" as="script">
复制代码
prefetch 是一个可选的、低优先级的用于获取在后续的导航中可能用到的一个资源的 fetc;preload 是一个强制的、高优先级的用于获取当前导航必需资源的 fetch。
若是你使用了懒加载来加速页面的加载,或者在 JavaScript 或 CSS 内部告诉了浏览器存在的资源,好比 web 字体,那么 preload 将很是有用。
这还有一个有趣的用例,你能够对预加载的资源进行更细粒度的控制:
<script> function preloadFinished(e) { ... } function preloadError(e) { ... } </script>
<!-- listen for load and error events -->
<link rel="preload" href="app.js" as="script" onload="preloadFinished()" onerror="preloadError()">
复制代码
你能够在这个网站查看浏览器的支持状况:caniuse.com/#feat=link-…
从 Safari Technology Preview 13 版本也开始提供这个功能了:developer.apple.com/safari/tech…
预渲染是一种告诉浏览器预取并执行给定资源的方法。
你能够经过插入 rel
为 prerender
的 link
元素来触发预渲染,例如:
<link rel='prerender' href='//pagetoprerender/landing.html'>
复制代码
你能够将预渲染视为在新选项卡中加载页面,只是该选项卡对用户隐藏,直到用户发出请求时才呈现。
因为浏览器会执行预渲染页面上的全部脚本,所以你可能会遇到一些意外的后果,好比触发 analytics beacons,而实际上页面并无被展现。你可使用 Page Visibility API 来解决这些问题。
你应该理性地使用 prerender,由于它可能会致使带宽和 CPU 使用的上升。你应该只在这种状况下考虑使用 prerender,那就是若是你对用户将要使用某个资源高度自信,而且你确实提供了附加的价值。
请注意,是否启动预渲染的决定权在于浏览器,它能够基于一组 预约义规则 选择不启动或放弃预渲染功能。
你能够在此查看浏览器的支持状况:caniuse.com/#feat=link-…
Hint probability 是一个 link
的元素的 pr
属性,可用于指示给定资源是否必要的几率,而且你能够将其与任何上面提到的资源提示一块儿使用,可是 preload 除外。
// The pr attribute expects a float value in the [0.0-1.0] range
<link rel="prefetch" href="//example.com/next-page.html" pr="0.75">
复制代码
这个 hint 用于帮助浏览器决定一个给定 hint 的执行。在设备中资源受限的状况下,浏览器能够决定仅执行高可用性提示。
上面提到的每一个 resource hint 均可以在运行时使用 JavaScript 触发,你只须要使用正确的属性建立 link
元素并将其添加到页面的 head
标签中。
var hint =document.createElement("link")
hint.setAttribute(“rel”,”prerender”)
hint.setAttribute(“href”,”next-page.html”)
document.getElementsByTagName(“head”)[0].appendChild(hint)
复制代码
对你的架构进行分析,找出能够从中获取最大收益的地方:
研究用户在你网站上的行为:
始终使用 webpagetest 等工具在更改先后进行速度测量。
能力越大,责任越大。