基於VUE的前端小站改形成SSR服務器端渲染後,HTML文檔會自動使用preload和prefetch來預加載所需資源,本文將詳細介紹preload和prefetch的使用css
在介紹preload和prefetch以前,首先要介紹瀏覽器的資源優先級前端
在Chrome瀏覽器中,不一樣的資源在瀏覽器渲染的不一樣階段進行加載的優先級不一樣windows
一共分紅五個級別跨域
Highest 最高
Hight 高
Medium 中等
Low 低
Lowest 最低
其中主資源HTML和CSS的優先級最高,其餘資源根據狀況的不一樣優先級不一瀏覽器
JS腳本根據它們在文件中的位置是否異步、延遲或阻塞得到不一樣的優先級:服務器
一、網絡在第一個圖片資源以前阻塞的腳本在網絡優先級中是中級網絡
二、網絡在第一個圖片資源以後阻塞的腳本在網絡優先級中是低級app
三、異步/延遲/插入的腳本(不管在什麼位置)在網絡優先級中是很低級異步
圖片(視口可見)將會得到相對於視口不可見圖片(低級)的更高的優先級(中級),因此某些程度上 Chrome 將會盡可能懶加載這些圖片。低優先級的圖片在佈局完成被視口發現時,將會得到優先級提高async
preload 使用 「as」 屬性加載的資源將會得到與資源 「type」 屬性所擁有的相同的優先級。好比說,preload as="style" 將會得到比 as=「script」 更高的優先級
不帶 「as」 屬性的 preload 的優先級將會等同於異步請求
【定義】
以下所示,preload是link元素中的rel屬性值
<link rel=「preload」>
preload 提供了一種聲明式的命令,讓瀏覽器提早加載指定資源(加載後並不執行),須要執行時再執行
這樣作的好處在於:
一、將加載和執行分離開,不阻塞渲染和document的onload事件
二、提早加載指定資源,再也不出現依賴的font字體隔了一段時間才刷出的狀況
【建立】
使用 link 標籤靜態標記須要預加載的資源
<link rel="preload" href="/path/to/style.css" as="style">
也可使用腳本動態建立一個 link 標籤後插入到 head 頭部
<script> const link = document.createElement('link'); link.rel = 'preload'; link.as = 'style'; link.href = '/path/to/style.css'; document.head.appendChild(link); </script>
【檢測】
在不支持 preload 的瀏覽器環境中,會忽略對應的 link 標籤,而若須要作特徵檢測的話,則可使用以下代碼
const isPreloadSupported = () => { const link = document.createElement('link'); const relList = link.relList; if (!relList || !relList.supports) { return false; } return relList.supports('preload'); }
【特性】
使用 preload 後,無論資源是否使用都將提早加載。若不肯定資源是一定會加載的,則不要錯誤使用 preload,以避免本末致使,給頁面帶來更沉重的負擔
Preload 有 as 屬性,瀏覽器能夠設置正確的資源加載優先級,這種方式能夠確保資源根據其重要性依次加載, 因此,Preload既不會影響重要資源的加載,又不會讓次要資源影響自身的加載;瀏覽器能根據 as 的值發送適當的 Accept 頭部信息;瀏覽器經過 as 值能得知資源類型,所以當獲取的資源相同時,瀏覽器可以判斷前面獲取的資源是否能重用
若是忽略 as 屬性,或者錯誤的 as 屬性會使 preload 等同於 XHR 請求,瀏覽器不知道加載的是什麼,所以會賦予此類資源很是低的加載優先級
Preload 的不同凡響還體如今 onload 事件上。也就是說能夠定義資源加載完畢後的回調函數
<link rel="preload" href="..." as="..." onload="preloadFinished()">
好比,可使用preload的樣式表當即生效
<link rel="preload" href="style.css" onload="this.rel=stylesheet">
此外,preload 不會阻塞 windows 的 onload 事件
對跨域的文件進行preload時,必須加上 crossorigin 屬性
<link rel="preload" as="font" crossorigin href="https://at.alicdn.com/t/font_zck90zmlh7hf47vi.woff">
【二次獲取】
一、不使用as屬性
若是對所 preload 的資源不使用明確的 「as」 屬性,將會致使二次獲取
二、字體文件
preload 字體不帶 crossorigin 會二次獲取! 確保對 preload 的字體添加 crossorigin 屬性,不然字體文件會被下載兩次,這個請求使用匿名的跨域模式。這個建議也適用於字體文件在相同域名下,也適用於其餘域名的獲取(好比說默認的異步獲取)
【警告】
沒有用到的 preload 資源在 Chrome 的 console 裏會在 onload 事件 3s 後發生警告
以下所示,prefetch是link元素中的rel屬性值
<link rel=「prefetch」>
它的做用是告訴瀏覽器加載下一頁面可能會用到的資源,注意,是下一頁面,而不是當前頁面。所以該方法的加載優先級很是低,也就是說該方式的做用是加速下一個頁面的加載速度
【區分】
preload 是告訴瀏覽器頁面一定須要的資源,瀏覽器必定會加載這些資源
prefetch 是告訴瀏覽器頁面可能須要的資源,瀏覽器不必定會加載這些資源
在VUE SSR生成的頁面中,首頁的資源均使用preload,而路由對應的資源,則使用prefetch
<link rel="preload" href="./manifest.js" as="script"> <link rel="preload" href="./vendor.js" as="script"> <link rel="preload" href="./app.js" as="script"> <link rel="prefetch" href="./vendor-async.js"> <link rel="prefetch" href="./user.js"> <link rel="prefetch" href="./comment.js"> <link rel="prefetch" href="./category.js"> <link rel="prefetch" href="./post.js"> <link rel="prefetch" href="./home.js">
因此,對於當前頁面頗有必要的資源使用 preload,對於可能在未來的頁面中使用的資源使用 prefetch
【不要混用】
preload 和 prefetch 混用的話,並不會複用資源,而是會重複加載
<link rel="preload" href="https://at.alicdn.com/t/font_zck90zmlh7hf47vi.woff" as="font"> <link rel="prefetch" href="https://at.alicdn.com/t/font_zck90zmlh7hf47vi.woff" as="font">
使用 preload 和 prefetch 的邏輯可能不是寫到一塊兒,但一旦發生對用一資源 preload 或 prefetch 的話,會帶來雙倍的網絡請求