Fetch Priority API 會指出資源對瀏覽器的相對優先順序。這可以實現最佳載入效能,並改善 Core Web Vitals。
當瀏覽器剖析網頁,並開始探索並下載圖片、指令碼或 CSS 等資源時,便會指派擷取 priority
,讓瀏覽器按照最佳順序下載這些內容。資源的優先順序通常取決於資源本身和文件中的位置。舉例來說,可視區域圖片的優先順序可能為 High
,且在 <head>
中使用 <link>
會禁止轉譯的 CSS 的優先順序可能是 Very High
。瀏覽器很適合用來指定適當的優先順序,但不一定在所有情況下都是最佳設定。
本頁將討論 Fetch Priority API 和 fetchpriority
HTML 屬性,這些屬性可讓您提示資源的相對優先順序 (high
或 low
)。擷取優先順序有助於最佳化 Core Web Vitals。
摘要
「擷取優先順序」的主要用途如下:
- 指定圖片元素上的
fetchpriority="high"
,藉此提高 LCP 圖片的優先順序,藉此加快 LCP 圖片的優先順序。 - 提高
async
指令碼的優先順序,使用比目前最常見的入侵行為更適用的語意 (為async
指令碼插入<link rel="preload">
)。 - 降低後置指令碼的優先順序,以便改善圖片的順序。
![幻燈片檢視畫面比較 Google 航班/機票首頁的兩項測試。使用底部的「擷取優先順序」提升主頁橫幅的優先順序,將 LCP 降低 0.7 秒。](https://web.developers.google.cn/static/articles/fetch-priority/image/a-filmstrip-view-comparin-298b8fe7eedbb.png?authuser=19&hl=zh-tw)
過去開發人員使用預先載入和預先連線功能,對資源優先順序的影響有限。您可以透過預先載入功能,讓瀏覽器預先載入重要資源,以便瀏覽器自然發現這些資源。對於不易找到的資源 (例如樣式表中包含的字型、背景圖片,或透過指令碼載入的資源),這項功能特別實用。預先連線有助於為跨來源伺服器暖機,並有助於改善第一個位元組時間等指標。如果您知道來源,但不一定是所需資源的確切網址,這個方法就很實用。
「擷取優先順序」與這些資源提示相輔相成。是一種透過 fetchpriority
屬性提供的標記型信號,開發人員可用來指出特定資源的相對優先順序。你也可以透過 JavaScript 和 Fetch API 使用這些提示,並搭配使用 priority
屬性,藉此控制針對資料擷取資源的優先順序。擷取優先順序也可以補充預先載入作業。使用「Largest Contentful Paint」圖片,預先載入後,其優先順序仍較低。如果遭到其他低優先順序的資源推送,使用「擷取優先順序」有助於加快圖片載入的速度。
資源優先順序
資源下載順序取決於瀏覽器指派給 網頁上每個資源可能影響優先運算的因素 邏輯如下:
- 資源類型 (例如 CSS、字型、指令碼、圖片和第三方資源)。
- 文件參照資源的位置或順序。
- 是否在指令碼中使用
async
或defer
屬性。
下表顯示 Chrome 如何排定大多數資源的優先順序及排序:
在版面配置封鎖階段中載入 | 在版面配置封鎖階段一次載入一次 | ||||
---|---|---|---|---|---|
閃爍 優先等級 |
VeryHigh | 高 | 中 | 低 | VeryLow |
DevTools Priority |
最高 | 高 | 中 | 低 | 最低價 |
主要資源 | |||||
CSS (舊版**) | CSS (延遲**) | CSS (媒體不符***) | |||
指令碼 (提前** 或不從預先載入掃描器執行) | 腳本 (延遲**) | 指令碼 (非同步) | |||
字型 | 字型 (rel=preload) | ||||
匯入 | |||||
圖片 (在可視區域中) | 圖片 (前 5 張圖片 > 10,000px2) | 圖片 | |||
媒體 (影片/音訊) | |||||
預先擷取 | |||||
XSL | |||||
XHR (同步) | XHR/fetch* (非同步) |
瀏覽器會依照搜尋順序,下載相同優先順序的資源。您可以在 Chrome 開發人員工具的「網路」分頁中載入網頁時,查看指派給不同資源的優先順序。(請務必以滑鼠右鍵按一下表格標題並勾選該欄,以便納入優先順序欄)。
![Chrome 開發人員工具的「Network」分頁,當中列出多種字型資源。這些項目的優先順序都是最高的。](https://web.developers.google.cn/static/articles/fetch-priority/image/a-screenshot-assets-list-fdcb380583bdd.png?authuser=19&hl=zh-tw)
type = "font"
的優先順序![Chrome 開發人員工具的「Network」分頁,當中列出多種字型資源。包括「低」和「高」優先順序。](https://web.developers.google.cn/static/articles/fetch-priority/image/a-screenshot-assets-list-f556ffc3eb8e4.png?authuser=19&hl=zh-tw)
type = "script"
的優先順序。優先順序改變時,您可以在「大型要求列」設定或工具提示中查看初始和最終的優先順序。
![Chrome 開發人員工具的「Network」分頁。「大型請求資料列」設定為固定狀態,「優先順序」欄會顯示第一張圖片 (順位為「高」),中的第一張圖片分別為「高」優先順序。工具提示也會顯示相同資訊。](https://web.developers.google.cn/static/articles/fetch-priority/image/initial-final-priority.png?authuser=19&hl=zh-tw)
您在什麼情況下需要擷取優先順序?
現在您已瞭解瀏覽器的優先順序邏輯,接下來就可以調整網頁的下載順序,藉此提升網頁效能和網站體驗核心指標。以下列舉幾個可以調整的項目,藉此影響資源下載的優先順序:
- 請按照您希望瀏覽器下載資源的順序放置
<script>
和<link>
等資源標記。一般來說,優先順序相同的資源會依照找到的順序載入。 - 使用
preload
資源提示提早下載必要資源,特別是瀏覽器不易找到的資源。 - 使用
async
或defer
下載指令碼,而不會封鎖其他資源。 - 延遲載入需捲動位置的內容,讓瀏覽器可以使用可用頻寬來處理更重要的不需捲動位置資源。
這些技術有助於提升瀏覽器的效能和網站體驗核心指標,有助於控制瀏覽器的優先順序。舉例來說,在預先載入重要背景圖片時,可以更快找出圖片,改善最大內容繪製 (LCP) 的成效。
這些控點有時可能不足以為應用程式妥善排定資源的優先順序。擷取優先順序的原因如下:
- 您有多個不需捲動位置的圖片,但並非所有圖片的優先順序必須相同。舉例來說,在圖片輪轉介面中,只有第一則顯示圖片需要較高的優先順序,其他圖片的初始優先順序通常可設為較低優先順序。
- 可視區域中的圖片優先順序通常是
Low
。版面配置完成後,Chrome 會偵測到他們位於可視區域,並提高版面配置的優先順序。一般來說,載入主要圖片 (例如主頁橫幅) 會大幅增加延遲。在標記中提供擷取優先順序,可讓圖片從High
的優先順序開始,及早開始載入。為了嘗試自動處理上述行為,Chrome 將前 5 張較大的圖片設為Medium
的優先順序,但明確來說fetchpriority="high"
的效果更好。
早期發現以 CSS 背景形式包含的 LCP 圖片時,仍須預先載入。如何強化背景圖片優先順序中應加入fetchpriority='high'
。 - 將指令碼宣告為
async
或defer
,會指示瀏覽器以非同步方式載入指令碼。不過,如優先順序表格所示,這些指令碼也會獲得「低」標籤優先順序。您可能會想要提高檔案的優先順序,同時確保非同步下載,特別是對使用者體驗至關重要的指令碼。 - 如果您使用 JavaScript
fetch()
API 以非同步方式擷取資源或資料,瀏覽器會指派High
的優先順序。您可能會希望部分擷取作業以較低優先順序執行,尤其是混合背景 API 呼叫與會回應使用者輸入內容的 API 呼叫時。將背景 API 呼叫標示為Low
優先順序,並將互動式 API 呼叫標示為High
的優先順序。 - 瀏覽器會將 CSS 和字型指派為
High
的優先順序,但這些資源部分資源的重要性可能高於其他。您可以使用「擷取優先順序」來降低非重要資源的優先順序 (請注意,早期的 CSS 會封鎖轉譯功能,因此優先順序通常為High
)。
fetchpriority
屬性
使用 link
、img
或 script
標記下載時,請使用 fetchpriority
HTML 屬性指定資源類型 (例如 CSS、字型、指令碼和圖片) 的下載優先順序。可能採用的值如下:
high
:資源的優先順序較高,而且只要瀏覽器的經驗法則不會妨礙發生,您希望瀏覽器優先處理資源的優先順序。low
:資源的優先順序較低,而您希望瀏覽器在啟發式演算法限制的情況下,再次降低該資源的優先順序。auto
:預設值,可讓瀏覽器選擇適當的優先順序。
以下列舉幾個在標記中使用 fetchpriority
屬性,以及與指令碼對等的 priority
屬性的範例。
<!-- We don't want a high priority for this above-the-fold image -->
<img src="/images/in_viewport_but_not_important.svg" fetchpriority="low" alt="I'm an unimportant image!">
<!-- We want to initiate an early fetch for a resource, but also deprioritize it -->
<link rel="preload" href="/js/script.js" as="script" fetchpriority="low">
<script>
fetch('https://example.com/', {priority: 'low'})
.then(data => {
// Trigger a low priority fetch
});
</script>
瀏覽器優先順序和 fetchpriority
的影響
您可以將 fetchpriority
屬性套用至不同資源,如下表所示,提高或降低運算的優先順序。每列的 fetchpriority="auto"
(↘) 會標示該資源類型的預設優先順序。(也可以以 Google 文件的形式存取)。
在版面配置封鎖階段中載入 | 在版面配置封鎖階段,一次載入一個項目 | ||||
---|---|---|---|---|---|
閃爍 優先等級 |
VeryHigh | 高 | 中 | 低 | VeryLow |
DevTools Priority |
最高 | 高 | 中 | 低 | 最低價 |
主要資源 | ◉ | ||||
CSS (舊版**) | ⬆◉ | ⬇ | |||
CSS (延遲**) | ⬆ | ◉ | ⬇ | ||
CSS (媒體不符***) | ⬆*** | ◉⬇ | |||
指令碼 (提前** 或不從預先載入掃描器執行) | ⬆◉ | ⬇ | |||
腳本 (延遲**) | ⬆ | ◉ | ⬇ | ||
指令碼 (非同步/延遲) | ⬆ | ◉⬇ | |||
字型 | ◉ | ||||
字型 (rel=preload) | ⬆◉ | ⬇ | |||
匯入 | ◉ | ||||
圖片 (在可視區域中 - 版面配置後) | ⬆◉ | ⬇ | |||
圖片 (前 5 張圖片 > 10,000px2) | ⬆ | ◉ | ⬇ | ||
圖片 | ⬆ | ◉⬇ | |||
媒體 (影片/音訊) | ◉ | ||||
XHR (同步) - 已淘汰 | ◉ | ||||
XHR/fetch* (非同步) | ⬆◉ | ⬇ | |||
預先擷取 | ◉ | ||||
XSL | ◉ |
fetchpriority
會設定「相對優先順序」,也就是將預設優先順序提高或降低適當的數量,而不是明確將優先順序設為 High
或 Low
。這通常會導致優先順序為 High
或 Low
,但並非一律如此。舉例來說,含有 fetchpriority="high"
的重要 CSS 保留了「非常高」/「最高」優先順序,在這些元素上使用 fetchpriority="low"
會保留「高」優先順序。這兩種情況都不會明確將優先順序設為 High
或 Low
。
用途
如要向瀏覽器提供額外的提示,指出擷取資源的優先順序,請使用 fetchpriority
屬性。
提高 LCP 映像檔的優先順序
您可以指定 fetchpriority="high"
來提高 LCP 或其他重要映像檔的優先順序。
<img src="lcp-image.jpg" fetchpriority="high">
以下比較 Google 航班/機票網頁中的 LCP 背景圖片,同時載入和未採用「擷取優先順序」原則。將優先順序設為高時,LCP 已從 2.6 秒提升至 1.9 秒。
降低不需捲動位置圖片的優先順序
使用 fetchpriority="low"
可降低不立即重要的不需捲動位置圖片的優先順序,例如圖片輪轉介面中的螢幕外圖片。
<ul class="carousel">
<img src="img/carousel-1.jpg" fetchpriority="high">
<img src="img/carousel-2.jpg" fetchpriority="low">
<img src="img/carousel-3.jpg" fetchpriority="low">
<img src="img/carousel-4.jpg" fetchpriority="low">
</ul>
雖然 2-4 張圖片在可視區域外,可能會視為「夠近」提高為 high
,即使新增了 load=lazy
屬性,也可以載入。因此,fetchpriority="low"
是正確的解決方案。
在我們之前對 Oodle 應用程式的實驗中,這是降低載入時不顯示圖片的優先順序。網頁載入時間縮短了 2 秒。
![用於 Oodle 應用程式圖片輪轉介面時的擷取優先順序並列比較。瀏覽器是在左側設定輪轉介面圖片的預設優先順序,但下載和繪製圖片的速度比右側範例要慢 2 秒,因此只對第一個輪轉介面圖片設定較高的優先順序。](https://web.developers.google.cn/static/articles/fetch-priority/image/a-side-side-comparison-54fe14438a5c2.png?authuser=19&hl=zh-tw)
降低預先載入資源的優先順序
如要防止預先載入的資源與其他重要資源競爭,您可以降低這些資源的優先順序。請搭配圖片、指令碼和 CSS 使用這項技巧。
<!-- Lower priority only for non-critical preloaded scripts -->
<link rel="preload" as="script" href="critical-script.js">
<link rel="preload" as="script" href="non-critical-script.js" fetchpriority="low">
<!-- Preload CSS without blocking render, or other resources -->
<link rel="preload" as="style" href="theme.css" fetchpriority="low" onload="this.rel='stylesheet'">
調整指令碼的優先順序
網頁需要互動的指令碼應能快速載入,但不應封鎖其他更關鍵且會妨礙顯示的資源。您可以將這些項目標示為「async
」並設為高優先順序。
<script src="async_but_important.js" async fetchpriority="high"></script>
如果指令碼需要使用特定的 DOM 狀態,就無法將指令碼標示為 async
。不過,如果網頁稍後會在網頁上執行,您可用較低的優先順序載入這些素材資源:
<script src="blocking_but_unimportant.js" fetchpriority="low"></script>
這樣做仍會封鎖剖析器抵達這個指令碼後的內容,但會在優先處理此事前的內容。
如果需要已完成的 DOM,您也可以使用 defer
屬性 (依序執行、在 DOMContentLoaded 後執行),甚至是頁面底部的 async
。
降低非重要資料擷取作業的優先順序
瀏覽器會以高優先順序執行 fetch
。如果您有多個擷取作業可能會同時觸發,可以將較重要的資料擷取作業設為高預設優先順序,並降低較不重要的資料優先順序。
// Important validation data (high by default)
let authenticate = await fetch('/user');
// Less important content data (suggested low)
let suggestedContent = await fetch('/content/suggested', {priority: 'low'});
擷取優先順序實作注意事項
擷取優先順序可針對特定用途提高效能,不過使用「擷取優先順序」時,請注意下列事項:
fetchpriority
屬性是提示,不是指令。瀏覽器會嘗試尊重開發人員的偏好設定,但也能對資源優先順序套用資源優先順序偏好設定,藉此解決衝突問題。請不要將「擷取優先順序」與預先載入設定混淆:
- 預先載入是強制擷取,而不是提示。
- 預先載入可讓瀏覽器提早探索資源,但仍會擷取採用預設優先順序的資源。相反地,「擷取優先順序」並不能提高曝光度,但可讓您提高或降低擷取優先順序。
- 相較於優先順序變更的效果,您可更容易觀察及測量預先載入的效果。
擷取優先順序可藉由提升優先順序的精細程度,彌補預先載入項目不足。如果您已經在 LCP 圖片的
<head>
中將預先載入項目指定為第一個項目,則high
擷取優先順序可能無法大幅改善 LCP。不過,如果預先載入是在其他資源載入後發生,high
擷取優先順序可進一步改善 LCP。如果重要圖片是 CSS 背景圖片,請使用fetchpriority = "high"
預先載入。在更多資源爭用可用網路頻寬的環境中,優先順序最佳化的載入時間會更加相關。HTTP/1.x 連線遇到無法平行下載的情況,或者在低頻寬 HTTP/2 或 HTTP/3 連線時很常見。在這種情況下,排定優先順序有助於解決瓶頸。
CDN 不會統一實作 HTTP/2 優先順序,也不會對 HTTP/3 採取類似做法。即使瀏覽器向「擷取優先順序」傳達優先順序,CDN 可能不會按照指定的順序重新排定資源的優先順序。這會使得測試擷取優先順序變得困難。優先順序會在瀏覽器內部以及支援優先順序的通訊協定 (HTTP/2 和 HTTP/3) 中套用。即使瀏覽器要求資源時,優先順序往往會變動,因此如果只有在內部瀏覽器優先順序無關 CDN 或來源支援的情況下,您還是應該使用「擷取優先順序」來排定內部瀏覽器的優先順序。舉例來說,當瀏覽器處理重要
<head>
項目時,系統通常不會要求要求圖片等低優先順序資源。您可能無法在初始設計中將「擷取優先順序」導入最佳做法。在之後的開發週期中,您可以將系統指派給網頁上不同資源的優先順序。如果這些優先順序與您的預期不符,可以引入「擷取優先順序」進行進一步的最佳化。
開發人員應基於預期用途預先載入剖析器未偵測到的資源 (字型、匯入內容、背景 LCP 圖片)。preload
提示的位置會影響資源預先載入的時間。
擷取優先順序是指資源擷取時應如何擷取資源。
預先載入的使用提示
使用預先載入功能時,請注意下列事項:
- 若在 HTTP 標頭中加入預先載入,則會優先將其放在載入順序中的所有其他項目之前。
- 一般來說,系統會按照剖析器 (優先順序為
Medium
以上) 的任何項目預先載入,並依序載入。如要在 HTML 開頭加入預先載入項目,請格外小心。 - 預先載入字型可能最適合用於開頭或內文開頭。
- 匯入預先載入項目 (動態
import()
或modulepreload
) 應在需要匯入的指令碼標記之後執行,因此請務必先載入或剖析指令碼,以便在依附元件載入時進行評估。 - 圖片預先載入的預設優先順序為
Low
或Medium
。根據非同步指令碼和其他低或最低優先順序的標記,排列這些代碼。
記錄
我們於 2018 年率先在 Chrome 中測試擷取優先順序功能,並於 2021 年使用 importance
屬性再次測試。當時稱為「優先提示」。在網路標準處理程序中,HTML 介面現已變更為 fetchpriority
,JavaScript 的 Fetch API 適用的介面現已變更為 priority
。為了減少混淆,我們現在稱之為 API 擷取優先順序。
結論
開發人員可能會對「擷取優先順序」有興趣,除了修正預先載入行為外,也很關注近期的重點是網站體驗核心指標和 LCP。現在,他們可以使用額外旋鈕來達成偏好的載入序列。