如何通過預載入 (Preload) 關鍵資源以提高網站載入速度

如何通過預載入 (Preload) 關鍵資源以提高網站載入速度

預載入允許您指定在頁面載入期間立即或很快需要的資源(例如字型、影象、JavaScript 和 CSS)。 在您網站的每個頁面的<head>…</head>部分頂部新增一個link rel='preload'標籤。

比如:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<link rel='preload' href='font.woff2' as='font' type='font/woff2' crossorigin>
<link rel='preload' href='font.woff2' as='font' type='font/woff2' crossorigin>
<link rel='preload' href='font.woff2' as='font' type='font/woff2' crossorigin>

開啟網頁時,瀏覽器會從伺服器請求HTML文件,解析其內容,併為引用資源提交單獨請求。作為開發人員,您知道頁面需要的所有資源以及哪些資源最為重要。您可以使用這些知識提前請求關鍵資源,加快載入的過程。本文介紹瞭如何使用 <link> 來達成此目的。

預載入的工作原理

預載入最適合用於瀏覽器通常較晚發現的資源。

預載入後期資源

在本例中,Pacifico字型是在樣式表通過 @font-face 規則定義的。瀏覽器只有在完成下載和解析樣式表後才會載入字型檔案。

通過預載入某個資源,您希望瀏覽器可以比正常發現它更早地獲取該資源,因為您認為它對當前頁面很重要。

預載入某個資源

在本例中,已預載入了Pacifico字型,所以下載會與樣式表並行進行。

關鍵請求鏈代表著瀏覽器優先處理和獲取的資源順序。 Lighthouse會將位於該鏈第三層的資產識別為後期發現的資產。您可以使用預載入關鍵請求審計來確定要預載入的資源。

預載入關鍵請求

您可以通過在HTML文件的頭部新增帶有 rel="preload" 的 <link> 標記來預載入資源:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<link as="script" href="critical.js">
<link as="script" href="critical.js">
<link as="script" href="critical.js">

瀏覽器會快取預載入的資源,以便在需要時立即可用。(它不會執行指令碼或應用樣式表。)

在實施預載入後,包括Shopify、Financial Times和Treebo在內的許多網站在以使用者為中心的指標(例如Time to InteractiveFirst Contentful Paint)等方面,都實現了1秒的改進。

瀏覽器會根據情況執行諸如 preconnect 和 prefetch 等資源提示。而另一方面,preload 對瀏覽器來說是強制性的。現代瀏覽器已經非常擅長對資源進行優先順序排序,這就是為什麼謹慎使用 preload 並且只預載入最關鍵的資源那麼重要。

load 事件後大約3秒會觸發Chrome中的控制檯警告。

謹慎使用 preload

所有現代瀏覽器均支援 preload

有助於修復以下兩種型別的警告:

1.預載入金鑰請求

預載入關鍵請求是Web字型的常見警告。Font Awesome是您可能會看到的一種非常常見的字型。

預載入關鍵請求

預載入關鍵請求

2.渲染阻塞資源

通過預載入,您還可以修復渲染阻塞資源警告,因為資產以非阻塞方式載入。

消除渲染阻塞資源

消除渲染阻塞資源

如果您正在預載入影象,它還可以幫助降低最大內容繪製 (LCP) 時間。

可預載入資源

有許多不同的資源可以預載入。

公共資源

  • font: 字型檔案。
  • script: JavaScript檔案。
  • style: CSS樣式表。
  • image: 影象檔案 ( .jpg.png.webp)。

其他資源

  • audio: 音訊檔案
  • document: 旨在由 <frame><iframe>嵌入的HTML文件。
  • embed:要嵌入到 <embed> 元素中的資源。
  • fetch:要通過fetch或XHR請求訪問的資源,例如ArrayBuffer或JSON檔案。
  • object:要嵌入到 <object> 元素中的資源。
  • track: WebVTT檔案。
  • worker:一個JavaScript網路worker或共享worker。
  • video: 視訊檔案。

注意:在撰寫本文時,Chrome存在一個未解決的bug,即預載入請求比其他更高優先順序資源的獲取速度更快。在解決此問題之前,請注意預載入的資源如何“跳過佇列”並比應有的時間更早地被請求。

預載入CSS中定義的資源

在瀏覽器下載並解析CSS檔案之前,不會發現這些檔案中使用 @font-face 規則定義的字型或背景影象。預載入這些資源可確保在下載CSS檔案之前獲取它們。

預載入CSS檔案

如果您使用了關鍵CSS方法,那麼CSS將分成兩部分。渲染首屏內容所需的關鍵CSS內聯在文件的 <head> 中,非關鍵CSS通常使用JavaScript延遲載入。在載入非關鍵CSS之前等待JavaScript執行會導致使用者滾動時呈現延遲,因此最好使用 <link> 更快地啟動下載。

預載入JavaScript檔案

由於瀏覽器不執行預載入的檔案,因此預載入有助於將獲取與執行分開,這可以改善Time to Interactive等指標。如果您拆分JavaScript包並僅預載入關鍵塊,則預載入效果最佳。

如何實現rel=preload

實現 preload 最簡單的方法是在文件的 <head> 中新增一個<link> 標記:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<head> <link as="script" href="critical.js"></head>
<head> <link as="script" href="critical.js"></head>
<head>  <link as="script" href="critical.js"></head>

提供 as 屬性可幫助瀏覽器根據其型別來設定預獲取資源的優先順序,設定正確的標頭,以及確定資源是否已存在於快取中。此屬性可接受的值包括: script 、style 、font 和 image 等等

請檢視Chrome Resource Priorities and Scheduling文件,詳細瞭解瀏覽器如何確定不同型別資源的優先順序。

注意:省略 as 屬性或使用了無效值,就相當於XHR請求,這時瀏覽器不知道它獲取的內容,因此無法確定正確的優先順序。它還可能導致某些資源(例如指令碼)被獲取兩次。

某些型別的資源,例如字型,以匿名模式載入。對於這些資源,您必須設定 preload 的 crossorigin 屬性:

<link href="ComicSans.woff2" as="font" type="font/woff2" crossorigin>

注意:沒有設定 crossorigin 屬性的預載入的字型將被獲取兩次!

另外,<link> 元素還接受 type 屬性,它包含連結資源的MIME型別。瀏覽器使用 type 屬性的值來確保資源僅在其檔案型別受支援時才被預載入。如果瀏覽器不支援指定的資源型別,它將忽略 <link> 。

請嘗試通過預載入web字型提高網頁效能

您可以通過 Link HTTP標頭預載入任何型別的資源:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
Link: </css/style.css>;; as="style"
Link: </css/style.css>;; as="style"
Link: </css/style.css>;; as="style"

在HTTP標頭中指定 preload 的一個好處是,瀏覽器不需要解析文件來發現它,這在某些情況下可以提供一些小幅改進。

使用webpack預載入JavaScript模組

如果您使用了建立應用程式構建檔案的模組打包器,則需要檢查它是否支援預載入標籤的注入。在webpack 4.6.0或更高版本中,它通過在 import()中使用magic comments(魔法註釋)支援預載入:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import(_/* webpackPreload: true */_ "CriticalChunk")
import(_/* webpackPreload: true */_ "CriticalChunk")
import(_/* webpackPreload: true */_ "CriticalChunk")

如果您使用的是舊版webpack,請使用第三方外掛,例如preload-webpack-plugin

預載入時要記住的事項

  • 不要預載入每個指令碼,否則它實際上會導致效能問題,例如增加總阻塞時間 (TBT)。預載入應該只用於立即需要的資源,因此它們以非阻塞方式載入。這通常用於網路字型、影象、CSS和JS。
  • 如果您正在使用快取清除技術(例如查詢字串domain.com/style.css?ver=1.0),請不要忘記瀏覽器會看到確切的URL。因此,您將需要使用查詢字串URL,或者您可以使用控制代碼動態預載入。
  • 如果您有一個CDN重寫您的資產的URL,請確保您要預載入的所有資源首先被正確地重寫。如果URL不匹配,您最終可能會載入資源兩次。
  • 如果您預載入樣式表 (CSS) 或指令碼 (JS),並且您正在使用外掛來組合您的CSS/JSS(AutoptimizeWP Rocket等),請確保從連線過程中排除您預載入的資源。否則,它可能會被打包兩次並最終在您的網站上放置更多程式碼。

小結

為提高網頁速度,請預載入瀏覽器來發現較晚的重要資源。預載入全部資源會適得其反,因此請謹慎使用 preload,並衡量它在現實中的影響。

via https://web.dev

評論留言