[譯] 資源提示 —— 什麼是 Preload,Prefetch 和 Preconnect?

原文發佈於個人 GitHub blog,歡迎關注javascript

原文: Resource Hints – What is Preload, Prefetch, and Preconnect?css

做者:BRIAN JACKSONhtml

今天咱們將研究一下能顯著提高頁面性能的方法 —— 資源提示與指令。你也許據說過 preload,prefetch 和 preconnect,但是咱們想研究的更深一點,搞清他們之間的區別而且充分的利用它們。它們帶來的好處包括容許前端開發人員來優化資源的加載,減小往返路徑而且在瀏覽頁面時能夠更快的加載到資源。前端

Preload

Preload 是一個新的控制特定資源如何被加載的新的 Web 標準,這是已經在 2016 年 1 月廢棄的 subresource prefetch 的升級版。這個指令能夠在 <link> 中使用,好比 <link rel="preload">。通常來講,最好使用 preload 來加載你最重要的資源,好比圖像,CSS,JavaScript 和字體文件。這不要與瀏覽器預加載混淆,瀏覽器預加載只預先加載在HTML中聲明的資源。preload 指令事實上克服了這個限制而且容許預加載在 CSS 和JavaScript 中定義的資源,並容許決定什麼時候應用每一個資源。java

Preload 與 prefetch 不一樣的地方就是它專一於當前的頁面,並以高優先級加載資源,Prefetch 專一於下一個頁面將要加載的資源並以低優先級加載。同時也要注意 preload 並不會阻塞 window 的 onload 事件。git

使用 Preload 的好處

使用 preload 指令的好處包括:github

  • 容許瀏覽器來設定資源加載的優先級所以能夠容許前端開發者來優化指定資源的加載。
  • 賦予瀏覽器決定資源類型的能力,所以它能分辨這個資源在之後是否能夠重複利用。
  • 瀏覽器能夠經過指定 as 屬性來決定這個請求是否符合 content security policy
  • 瀏覽器能夠基於資源的類型(好比 image/webp)來發送適當的 accept 頭。

舉例

這裏有一個很是基本的預加載圖像的例子:web

<link rel="preload" href="image.png">
複製代碼

這裏有一個預加載字體的例子,記住:若是你的預加載須要 CORS 的跨域請求,那麼也要加上 crossorigin 的屬性。chrome

<link rel="preload" href="https://example.com/fonts/font.woff" as="font" crossorigin>
複製代碼

這裏有一個經過 HTML 和 JavaScript 預加載樣式表的例子:api

<!-- Via markup -->
<link rel="preload" href="/css/mystyles.css" as="style">
複製代碼
<!-- Via JavaScript --> 
<script> var res = document.createElement("link"); res.rel = "preload"; res.as = "style"; res.href = "css/mystyles.css"; document.head.appendChild(res); </script>
複製代碼

來自 filament group 的 Scott Jehl 也有了一些相關研究並寫了 async loaded styles using markup 說明了 preload 是不阻塞頁面渲染的!

瀏覽器對 Preload 的支持

Chrome 50 在 2016 年 4 月添加了對 Preload 的支持,Opera 37 等瀏覽器也支持它。不過目前 Mozilla Firefox 尚未肯定要支持,Microsoft Edge 開發者版彷佛要支持。

(譯者注,下圖是 2018 年 7 月末瀏覽器對 preload 的支持狀況)

1532588712620

能夠讀一下咱們對 preload 的一篇深刻分析的文章。

Prefetch

Prefetch 是一個低優先級的資源提示,容許瀏覽器在後臺(空閒時)獲取未來可能用獲得的資源,而且將他們存儲在瀏覽器的緩存中。一旦一個頁面加載完畢就會開始下載其餘的資源,而後當用戶點擊了一個帶有 prefetched 的鏈接,它將能夠馬上從緩存中加載內容。有三種不一樣的 prefetch 的類型,link,DNS 和 prerendering,下面來詳細分析。

Link Prefetching

像上面提到的,link prefetching 假設用戶將請求它們,因此容許瀏覽器獲取資源並將他們存儲在緩存中。瀏覽器會尋找 HTML <link> 元素中的 prefetch 或者 HTTP 頭中以下的 Link:

  • HTML: <link rel="prefetch" href="/uploads/images/pic.png">
  • HTTP Header: Link: </uploads/images/pic.png>; rel=prefetch

"這項技術有爲不少有交互網站提速的潛力,但並不會應用在全部地方。對於某些站點來講,太難猜想用戶下一步的動向,對於另外一些站點,提早獲取資源可能致使數據過時失效。還有很重要的一點,不要過早進行 prefetch,不然會下降你當前瀏覽的頁面的加載速度 —— Google Developers"

除了 Safari, iOS Safari 和 Opera Mini,現代瀏覽器已經支持了 link Prefetch,Chrome 和 Firefox 還會在網絡面板上顯示這些 prefetched 資源。

(譯者注,下圖是 2018 年 7 月末瀏覽器對 link prefetch 的支持狀況)

1532588755398

DNS Prefetching

DNS prefetching 容許瀏覽器在用戶瀏覽頁面時在後臺運行 DNS 的解析。如此一來,DNS 的解析在用戶點擊一個連接時已經完成,因此能夠減小延遲。能夠在一個 link 標籤的屬性中添加 rel="dns-prefetch' 來對指定的 URL 進行 DNS prefetching,咱們建議對 Google fonts,Google Analytics 和 CDN 進行處理。

"DNS 請求在帶寬方面流量很是小,但是延遲會很高,尤爲是在移動設備上。經過 prefetching 指定的 DNS 能夠在特定的場景顯著的減少延遲,好比用戶點擊連接的時候。有些時候,甚至能夠減少一秒鐘的延遲 —— Mozilla Developer Network"

這也對須要重定向的資源頗有用,以下:

<!-- Prefetch DNS for external assets -->
 <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">
複製代碼

不過要注意的是 Chrome 已經在敲擊地址欄的時候作了相似的事情,好比 DNS preresolve 和 TCP preconnect,這些措施太酷了!你能夠經過 chrome://dns/ 來查看你的優化列表。

你能夠利用 Pagespeed 的過濾器 insert_dns_prefetch 來自動化的爲全部域名插入 <link rel="dns-prefetch">

DNS prefetch 已經被除了 Opera Mini 以外的全部現代瀏覽器支持了。

(譯者注,下圖是 2018 年 7 月末瀏覽器對 DNS-prefetch 的支持狀況)

1532591919917

Prerendering

Prerendering 和 prefetching 很是類似,它們都優化了可能導航到的下一頁上的資源的加載,區別是 prerendering 在後臺渲染了整個頁面,整個頁面全部的資源。以下:

<link rel="prerender" href="https://www.keycdn.com">
複製代碼

"prerender 提示能夠用來指示將要導航到的下一個 HTML:用戶代理將做爲一個 HTML 的響應來獲取和處理資源,要使用適當的 content-types 獲取其餘內容類型,或者不須要 HTML 預處理,可使用 prefetch。—— W3C"

Source: Chrome Prerendering

要當心的使用 prerender,由於它將會加載不少資源而且可能形成帶寬的浪費,尤爲是在移動設備上。還要注意的是,你沒法在 Chrome DevTools 中進行測試,而是在 chrome://net-internals/#prerender 中看是否有頁面被 prerendered 了,你也能夠在 prerender-test.appspot.com 進行測試。

除了 Mozilla Firefox,Safari,iOS Safari,Opera Mini 和 Android 瀏覽器外的一些現代瀏覽器已經支持了 prerendering。

1532586487867

除了多餘的資源加載外,使用 prefetch 還有一切 額外的反作用,好比對隱私的損害:

  • Web 統計將會收到影響而變大,儘管 Google 說已經限制了這個標籤。看看這個關於頁面分析將會被影響而在一次點擊時產生兩個 session 的 文章
  • 因爲可能從未訪問的站點下載了更多的頁面(尤爲是隱匿下載正在變得更加先進和多樣化),用戶的安全將面臨更多的風險。
  • 若是預取訪問未經受權的內容,用戶可能違反其網絡或組織的可接受使用策略。

能夠讀一下咱們對 prefetching 的一篇深刻分析的文章。

Preconnect

本文介紹的最後一個資源提示是 preconnect,preconnect 容許瀏覽器在一個 HTTP 請求正式發給服務器前預先執行一些操做,這包括 DNS 解析,TLS 協商,TCP 握手,這消除了往返延遲併爲用戶節省了時間。

"Preconnect 是優化的重要手段,它能夠減小不少請求中的往返路徑 —— 在某些狀況下能夠減小數百或者數千毫秒的延遲。—— lya Grigorik"

preconnect 能夠直接添加到 HTML 中 link 標籤的屬性中,也能夠寫在 HTTP 頭中或者經過 JavaScript 生成,以下是一個爲 CDN 使用 preconnect 的例子:

<link href="https://cdn.domain.com" rel="preconnect" crossorigin>
複製代碼

以下是爲 Google Fonts 使用 preconnect 的例子,經過給 fonts.gstatic.com 加入 preconnect 提示,瀏覽器將馬上發起請求,和 CSS 請求並行執行。在這個場景下,preconnect 從關鍵路徑中消除了三個 RTTs(Round-Trip Time)減小了超過半秒的延遲,lya Grigorik 的 eliminating RTTS with preconnect 一文中有更詳細的分析。

preconnect

使用 preconnect 是個有效並且剋制的資源優化方法,它不只能夠優化頁面而且能夠防止資源利用的浪費。除了 Internet Explorer,Safari,IOS Safari 和 Opera Mini 的現代瀏覽器已經支持了 preconnect。

1532588420933

能夠讀一下咱們對 preconnect 的一篇深刻分析的文章。

總結

但願你如今對 preload,prefetch 和 preconnect 有了一些理解並知道如何利用它們來加速資源的加載,但願在將來的幾個月能看到更多的瀏覽器支持這些預加載提示而且有更多的開發者使用它們。

你對這些資源提示有何理解?你試着使用過它們嗎?歡迎留言討論。

相關的資源提示文章

參考

相關文章
相關標籤/搜索