翻譯自: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 等工具在更改先後進行速度測量。
能力越大,責任越大。