性能優化小冊 - 讓頁面更早的渲染:使用 preload 提高資源加載優先級

preload 是一個新的 Web 標準,旨在提升性能以及提供給 web 開發者更多的細粒度加載控制。它可使開發者自定義加載邏輯而避免以 script 標籤加載資源所帶來的性能損耗。

preload 能夠指明哪些資源在頁面加載的生命週期的早期階段就開始獲取,在瀏覽器的主渲染機制介入前就進行預加載。這一機制使得資源能夠更早的獲得加載並可用,且更不易阻塞頁面的初步渲染,進而提高性能。css

preload 提供的好處主要是:html

  • 將加載和執行分離,可不阻塞渲染和 documentonload 事件。
  • 提早加載指定資源,再也不出現依賴的 font 字體隔了一段時間才刷出。
  • 能夠去更早地加載晚出現的資源。

哪些類型的資源可使用 preload?

  • vaudio: 音頻文件。
  • document: 一個將要被嵌入到 <frame><iframe> 內部的 HTML 文檔。
  • embed: 一個將要被嵌入到 <embed> 元素內部的資源。
  • fetch: 那些將要經過 fetch 和 XHR 請求來獲取的資源,好比一個 ArrayBuffer 或 JSON 文件。
  • font: 字體文件。
  • image: 圖片文件。
  • object: 一個將會被嵌入到 <embed> 元素內的文件。
  • script: JavaScript 文件。
  • style: 樣式表。
  • track: WebVTT 文件。
  • worker : 一個 JavaScript 的 web worker 或 shared worker。
  • video: 視頻文件。

如何使用 preload?

使用 link 標籤

<!-- 使用 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>

使用 as 來指定將要預加載的內容的類型,將使得瀏覽器可以:webpack

  • 更精確地優化資源加載優先級。
  • 匹配將來的加載需求,在適當的狀況下,重複利用同一資源。
  • 爲資源應用正確的內容安全策略。
  • 爲資源設置正確的 Accept 請求頭。

使用 HTTP 響應頭的 Link 字段建立

Link: <https://example.com/other/styles.css>; rel=preload; as=style

更早的加載

使用 preload 前,在遇到資源依賴時纔會進行加載:git

使用 preload 後,瀏覽器會進行資源調度,將 link 指定的資源優先加載,無論資源是否使用:github

但使用 preload 時須要注意如下幾點。web

1. 不要濫用 preload。

若不肯定資源是一定會使用的,則不要無心義的使用 preload,在移動端則須要特別慎重,由於可能會浪費用戶的帶寬。編程

2. preload 會使資源優先加載,但不必定會提高優先級(Priority)。

是否相同優先級
  ?是否使用 preload
    ? preload 指定的資源先加載
    : 根據 Queue 順序加載 
  : 根據優先級權重加載

使用 preload 會減小線程的 Queueing 時間,可是不必定會提升資源優先級。下圖爲使用 preload 的先後對比。segmentfault

3. 不要混淆 preload 和 prefetch。

<!-- 預測 -->
<link rel="preload" href="a.css">
<!-- 確認 --> 
<link rel="prefetch" href="b.css">

prefetch一種指望,預測會加載指定的資源,以備下一個導航或者下一屏頁面使用,但對當前的頁面並無什麼幫助。若是 prefetch 使用不得當,還會形成資源重複加載的問題。頁面不必定會使用 prefetch 指定的資源。跨域

preload一種確定,確認會加載指定資源,在頁面加載的生命週期的早期階段就開始獲取,不區分下一屏。頁面必定會使用 preload 指定的資源(不使用將會報警告⚠️)。瀏覽器

4. 使用 preload 預加載跨域資源時,須要設置 crossorigin 屬性。

若是你須要獲取的是 font 文件,那麼即便是非跨域的狀況下,也須要設置 crossorigin

<link rel="preload" href="https://mdn.github.io/html-examples/link-rel-preload/fonts/fonts/cicle_fina-webfont.woff2 " as="font" crossorigin="anonymous">

若不指定 crossorigin 屬性,則會採用匿名模式的 CORS 去加載。這樣可能會致使由於優先級的不一樣而重複加載資源文件的問題。

更多 preload 示例介紹

總結

  • 資源優先級 Priority 會隨着瀏覽器進程的不一樣階段動態變化的。
  • 更早的加載意味着更早的渲染。
  • prefetchpreconnect 都屬於預加載機制,但 preload 在大多數狀況下更符合需求和預期。

同系列文章:

參考:

Preload: What Is It Good For? - https://www.smashingmagazine....

用 preload 預加載頁面資源 - https://mp.weixin.qq.com/s/yt...

相關文章
相關標籤/搜索