資源預加載preload和資源預讀取prefetch簡明學習


前面的話

  基於VUE的前端小站改造成SSR服務器端渲染后,HTML文檔會自動使用preload和prefetch來預加載所需資源,本文將詳細介紹preload和prefetch的使用

 

資源優先級

  在介紹preload和prefetch之前,首先要介紹瀏覽器的資源優先級

property

  在Chrome瀏覽器中,不同的資源在瀏覽器渲染的不同階段進行加載的優先級不同

  一共分成五個級別

Highest 最高
Hight 高
Medium 中等
Low 低
Lowest 最低

  其中主資源HTML和CSS的優先級最高,其他資源根據情況的不同優先級不一

  JS腳本根據它們在文件中的位置是否異步、延遲或阻塞獲得不同的優先級:

  1、網絡在第一個圖片資源之前阻塞的腳本在網絡優先級中是中級

  2、網絡在第一個圖片資源之后阻塞的腳本在網絡優先級中是低級

  3、異步/延遲/插入的腳本(無論在什么位置)在網絡優先級中是很低級

  圖片(視口可見)將會獲得相對於視口不可見圖片(低級)的更高的優先級(中級),所以某些程度上 Chrome 將會盡量懶加載這些圖片。低優先級的圖片在布局完成被視口發現時,將會獲得優先級提升

  preload 使用 “as” 屬性加載的資源將會獲得與資源 “type” 屬性所擁有的相同的優先級。比如說,preload as="style" 將會獲得比 as=“script” 更高的優先級

  不帶 “as” 屬性的 preload 的優先級將會等同於異步請求

 

preload

【定義】

  如下所示,preload是link元素中的rel屬性值

<link rel=“preload”> 

  preload 提供了一種聲明式的命令,讓瀏覽器提前加載指定資源(加載后並不執行),需要執行時再執行

  這樣做的好處在於:

  1、將加載和執行分離開,不阻塞渲染和document的onload事件

  2、提前加載指定資源,不再出現依賴的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">

【二次獲取】

  1、不使用as屬性

  如果對所 preload 的資源不使用明確的 “as” 屬性,將會導致二次獲取

  2、字體文件

  preload 字體不帶 crossorigin 會二次獲取! 確保對 preload 的字體添加 crossorigin 屬性,否則字體文件會被下載兩次,這個請求使用匿名的跨域模式。這個建議也適用於字體文件在相同域名下,也適用於其他域名的獲取(比如說默認的異步獲取)

【警告】

  沒有用到的 preload 資源在 Chrome 的 console 里會在 onload 事件 3s 后發生警告

warn

 

prefetch

  如下所示,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 的話,會帶來雙倍的網絡請求

preload

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM