HTML link標籤中preload,prefetch,dns-prefetch,preconnect,prerender
Preload
在我們的瀏覽器載入資源的時候,對於每一個資源都有其自身的預設優先順序,倘若我們能修改每一個資源的預設優先順序,那我們幾乎可以按照我們的預期載入想要載入的資源。
以谷歌瀏覽器為例,我們開啟控制檯,並切換到Network選項,點選重新整理頁面,在網路下面的title一行點選滑鼠右鍵,勾選Priority即可看到載入資源的優先順序,我們可以看到樣式的級別比指令碼的優先順序高,畢竟頁面的一載入進來肯定是樣式首先需要渲染的,不然整個頁面便會四分五裂,使用者體驗不好。
preload一旦啟用後便會告知瀏覽器應該儘快的載入某個資源,如果提取的資源3s內未在當前使用,在谷歌開發工具將會觸發警告訊息:
preload語法如下:
1 <link rel="preload" as="script" href="foo.js"> 2 <link rel="preload" as="style" href="bar.css">
除了以上指定的資源外,還可以載入audio、font、video以及document等,詳情點選這裡瞭解。
跨域資源處理
如需載入跨域的資源列表,則需要正確設定CORS,接著便可以在<link>元素中設定好crossorigin屬性即可:
1 <link rel="preload" as="font" crossorigin="crossorigin" type="font/woff2" href="foo.woff2">
這裡有一個特例便是無論是否跨域,字型的獲取都需要設定crossorigin屬性,這是由於歷史原因造成,有興趣瞭解可移步這裡瞭解,另外我們還可以使用media響應式的載入圖片,比如:
1 <link rel="preload" href="[email protected]" as="image" media="(max-width: 325px)"> 2 <link rel="preload" href="[email protected]" as="image" media="(min-width: 400px)">
另一個重要的地方便是如果預載入一個指令碼,它並不是執行:
1 //只拉取下載不執行2 var preloadLink = document.createElement("link"); 3 preloadLink.href = "foo.js"; 4 preloadLink.rel = "preload"; 5 preloadLink.as = "script"; 6 document.head.appendChild(preloadLink); 7 8 //如果需要執行 9 var preloadedScript = document.createElement("script"); 10 preloadedScript.src = "foo.js"; 11 document.body.appendChild(preloadedScript);
preload相容性
相容似乎IE全體陣亡,edge也得17+才能勉強支援,火狐需要手動啟動支援,移動端支援程度還是挺好的。
Prefetch
簡而言之預提取就是在我們頁面載入完成後,在頻寬可用的情況下,載入使用者下一步期待的頁面資源,比如企業認證,一般都是分好幾個頁面進行認證的,在使用者從第一個頁面進行認證的時候,在頁面載入完成,使用者正在填寫表單資料之時,載入第二個頁面的部分資源,從而使使用者更快開啟下一個頁面,從而增加使用者體驗,示例:1 <link rel="prefetch" href="demo.html"> 2 <link rel="stylesheet" href="demo.css">當瀏覽器解析到link標籤時,讀取到rel的值為prefetch,便會將這一個資源新增的佇列中,當瀏覽器空閒時便會預提取資源,但是在demo.html頁面中只是載入HTML,不會載入demo頁面裡面的任何其他資源,除非你在demo頁面也明確使用了預提取。 Pretetch相容性 各大瀏覽器支援都還挺好,IE11+以上,但是Safari貌似到現在還沒支援(但是看WKWebView的原始碼,是支援了的)
DNS-Prefetch
我們都知道,當我們在瀏覽器的位址列輸入域名的時候,首先要進行的就是域名解析,因為我們需要載入域名對應的資源,這個過程很快,但是如果在移動端,那可是一個分秒必爭的地方,當一個頁面需要訪問許多外部域名的資源的時候,如果我們能在使用者瀏覽頁面的時候,在瀏覽器空閒的時間,把可能需要訪問的域名都提前做好了域名解析,那是不是大大增加了使用者開啟頁面的響應時間,增加使用者體驗,為了解決這個問題,w3c便提出來一個標準,學名叫dns-prefetch。使用方法上面中已經支援了,指定rel=”dns-prefetch”,在href中指定頁面需要解析的域名即可,你可能已經注意到了上面的圖中域名使用了雙斜槓,這個雙斜槓表示URL以主機名開頭,和你使用完整URL(比如http://g.alicdn.com/)是等效的。在RFC1808中被指定。
當然並不是所有的頁面需要用到的外部域名都需要做這樣的域名解析,瀏覽器預設會解析超連結屬性的href裡面的域名,並且你的網站域名還不能是HTTPS,如果是HTTPS,則需要設定請求頭或加入一段強制開啟域名解析的meta標籤。
1 //HTTP 2 <link rel="dns-prefetch" href="//a.com"> //多餘 3 <a href="http://a.com"> 4 //HTTPS 5 <meta http-equiv="x-dns-prefetch-control" content="on">//強制開啟 6 <a href="http://a.com">
當然,並不建議對HTTPS網站開啟強制解析的方式,因為這樣會帶來一些安全隱患,具體可參考這裡。
Preconnect
預連線,也就是啟動早期連線(包括DNS查詢,TCP握手和可選TLS協商),我們來看一個例子:
1 <link href='https://fonts.demo.com' rel='preconnect' crossorigin> 2 <link href='https://demo.com/css?family=黑體' rel='stylesheet'>
一個網路字型正常載入一般都包括:
- 頁面載入樣式,解析樣式用到的網路字型
- 網路字型開始下載,首先開始DNS的查詢
- 然後TCP握手
- 如果是HTTPS,還有TLS協商,最後下載字型
當然如果是跨域資源,不要忘了加上crossorigin屬性。
Preconnect相容性
IE15+以上部分相容,移動端相容良好。
Prerender
預渲染,簡單來說就是瀏覽器會下載指定連結的資源,並下載以及渲染它,就好比我們打開了一個新的Tab標籤頁,靜默的在後臺的下載執行,當然,瀏覽器也不一定會下載渲染它,這取決預很多情況,比如瀏覽器是否空閒以及作業系統是否會放棄下載過慢的資原始檔。
除非你真的能十分的肯定使用者接下來一定會觸發你所指定的資源地址,否則對於使用者來說這是一種頻寬的浪費,使用例子如下:
1 <link rel="prerender" href="https://www.apple.com/">
Prerender相容性
雖然是prerender是HTML5規範的一部分,但是似乎很多廠商都還沒有實現,但是IE11竟然支援。
結尾
講了這麼多,最後整理了一個表格,幫助大家快速查閱參考,每個瀏覽器的實施細節都有所區別,這裡以Chrome瀏覽器表格為例:
原文連結:https://www.jianshu.com/p/14b4cbce5e27