預(yù)加載
預(yù)加載是瀏覽器對(duì)將來(lái)可能被使用資源的一種暗示,一些資源可以在當(dāng)前頁(yè)面使用到纬霞,一些可能在將來(lái)的某些頁(yè)面中被使用凌埂。作為開(kāi)發(fā)人員,我們比瀏覽器更加了解我們的應(yīng)用诗芜,所以我們可以對(duì)我們的核心資源使用該技術(shù)
當(dāng)提到前端性能優(yōu)化時(shí)瞳抓,我們首先會(huì)聯(lián)想到文件的合并、壓縮伏恐,文件緩存和開(kāi)啟服務(wù)器端的 gzip 壓縮等孩哑,這使得頁(yè)面加載更快,用戶可以盡快使用我們的 Web 應(yīng)用來(lái)達(dá)到他們的目標(biāo)翠桦。
資源預(yù)加載是另一個(gè)性能優(yōu)化技術(shù)横蜒,我們可以使用該技術(shù)來(lái)預(yù)先告知瀏覽器某些資源可能在將來(lái)會(huì)被使用到。
以前這種實(shí)踐也被稱為prebrowsing
销凑。但這并不是一種單一的技術(shù)丛晌,實(shí)際上可以拆分成很多小點(diǎn):dns-prefetch
, subresource
, prefetch
, preconnect
和 prerender
DNS 預(yù)解析 DNS-Prefetch
DNS-Prefetch通過(guò)指定具體的URL來(lái)告知客戶端未來(lái)會(huì)用到相關(guān)的資源,這樣瀏覽器可以盡早的解析DNS斗幼。
例如澎蛛,我們將來(lái)可能從 example.com 獲取圖片或音頻資源,那么可以在文檔頂部的 <head> 標(biāo)簽中加入以下內(nèi)容:
<link rel="dns-prefetch" >
通過(guò)簡(jiǎn)單的一行代碼就可以告知那些兼容的瀏覽器進(jìn)行 DNS 預(yù)解析孟岛,這意味著當(dāng)瀏覽器真正請(qǐng)求該域中的某個(gè)資源時(shí)瓶竭,DNS 的解析就已經(jīng)完成了督勺。
項(xiàng)目中有用到第三方的代碼時(shí)這么做尤其有益;其他的使用場(chǎng)景斤贰,比如當(dāng)靜態(tài)資源和HTML不在一個(gè)域上智哀,而在CDN上;又比如在重定向前可以加上DNS prefetch荧恍。
預(yù)連接 Preconnect
與 DNS 預(yù)解析類似瓷叫,Preconnect 不僅完成 DNS 預(yù)解析,同時(shí)還將進(jìn)行 TCP 握手和建立傳輸層協(xié)議送巡。
用法如下:
<link rel="preconnect" >
現(xiàn)代瀏覽器都試著預(yù)測(cè)網(wǎng)站將來(lái)需要哪些連接摹菠,然后預(yù)先建立 socket 連接,從而消除昂貴的 DNS 查找骗爆、TCP 握手和 TLS 往返開(kāi)銷次氨。然而,瀏覽器還不夠聰明摘投,并不能準(zhǔn)確預(yù)測(cè)每個(gè)網(wǎng)站的所有預(yù)鏈接目標(biāo)煮寡。好在,在 Firefox 39 和 Chrome 46 中我們可以使用 Preconnect 告訴瀏覽器我們需要進(jìn)行哪些預(yù)連接犀呼。
預(yù)獲取 Prefetch
如果我們確定某個(gè)資源將來(lái)一定會(huì)被使用到幸撕,我們可以讓瀏覽器預(yù)先請(qǐng)求該資源并放入瀏覽器緩存中。與 DNS 預(yù)解析不同外臂,預(yù)獲取真正請(qǐng)求并下載了資源坐儿,并儲(chǔ)存在緩存中。
例如宋光,一個(gè)圖片和腳本或任何可以被瀏覽器緩存的資源:
<link rel="prefetch" href="image.png">
然而 預(yù)獲取還依賴于一些條件貌矿,某些預(yù)獲取可能會(huì)被瀏覽器忽略,例如從一個(gè)非常緩慢的網(wǎng)絡(luò)中獲取一個(gè)龐大的字體文件罪佳。并且站叼,F(xiàn)irefox 只會(huì)在瀏覽器閑置時(shí)進(jìn)行資源預(yù)獲取。
預(yù)獲取對(duì) webfonts 性能提升非常明顯菇民。目前,字體文件必須等到 DOM 和 CSS 構(gòu)建完成之后才開(kāi)始下載投储,使用預(yù)獲取就可以輕松繞過(guò)該瓶頸第练。
注意:要測(cè)試資源的預(yù)獲取有點(diǎn)困難,但在 Chrome 和 Firefox 的網(wǎng)絡(luò)面板中都有資源預(yù)獲取的記錄玛荞。還需要記住娇掏,預(yù)獲取的資源沒(méi)有同源策略的限制。
Subresources
Subresources是另一個(gè)預(yù)獲取方式勋眯,這種方式指定的預(yù)獲取資源具有最高的優(yōu)先級(jí)婴梧,在所有
prefetch
項(xiàng)之前進(jìn)行
<link rel="subresource" href="styles.css">
- rel=prefetch 為將來(lái)的頁(yè)面提供了一種低優(yōu)先級(jí)的資源預(yù)加載方式
- rel=subresource 為當(dāng)前頁(yè)面提供了一種高優(yōu)先級(jí)的資源預(yù)加載
所以下梢,如果資源是當(dāng)前頁(yè)面必須的,或者資源需要盡快可用塞蹭,那么最好使用 subresource
而不是 prefetch
孽江。
預(yù)渲染 Prerender
預(yù)渲染類似于在一個(gè)隱藏的 tab 頁(yè)中打開(kāi)了某個(gè)鏈接 – 將下載所有資源、創(chuàng)建 DOM 結(jié)構(gòu)番电、完成頁(yè)面布局岗屏、應(yīng)用 CSS 樣式和執(zhí)行 JavaScript 腳本等。當(dāng)用戶真正訪問(wèn)該鏈接時(shí)漱办,隱藏的頁(yè)面就切換為可見(jiàn)这刷,使頁(yè)面看起來(lái)就是瞬間加載完成一樣。
用法如下:
<link rel="prerender" >
這是一個(gè)核武器娩井,因?yàn)?code>prerender 可以預(yù)先加載文檔的所有資源暇屋。Google 搜索在其即時(shí)搜索頁(yè)面中已經(jīng)應(yīng)用該技術(shù)多年了,微軟也宣稱將在 IE11 中支持該特性洞辣。
需要注意的是不要濫用該特性咐刨,當(dāng)你知道用戶一定會(huì)點(diǎn)擊某個(gè)鏈接時(shí)才可以進(jìn)行預(yù)渲染,否則瀏覽器將無(wú)條件地下載所有預(yù)渲染需要的資源屋彪。
Preload
Preload 是一個(gè)新規(guī)范所宰,該規(guī)范還沒(méi)有被所有瀏覽器兼容。
Preload 草案建議允許始終預(yù)加載某些資源畜挥,不像Prefetch有可能被瀏覽器忽略仔粥,瀏覽器必須請(qǐng)求Preload標(biāo)記的資源。
用法如下:
<link rel="preload" href="image.png">
總結(jié)
文章說(shuō)的大部分預(yù)加載技術(shù)移動(dòng)端都不支持蟹但,PC支持有限躯泰,但我們顯然應(yīng)該知道這些技術(shù)的存在,并且持續(xù)的關(guān)注华糖。
預(yù)測(cè)用戶下一步將訪問(wèn)哪些資源是困難的麦向,需要進(jìn)行大量的測(cè)試,但是這帶來(lái)的性能提升是明顯的客叉。如果我們?cè)敢鈬L試這些預(yù)獲取技術(shù)诵竭,一定會(huì)顯著提升用戶的體驗(yàn)。