【譯】我們對 2023 年核心頁面指標的建議

2023-01-19 09:00:41

  原文地址:https://web.dev/top-cwv-2023,在正文開始前,推薦一款前端監控指令碼:shin-monitor,它能監控前端的錯誤、通訊、列印等行為,以及計算各類效能引數,包括 FMP、LCP、FP 等。

  我們 Google 希望我們的效能建議側重於:

  • 對現實世界產生最大影響的建議
  • 與大多數網站相關且適用的建議
  • 大多數開發人員可以實施的建議

  在過去的一年裡,我們花了很多時間來稽核我們提出的全套效能建議,並根據上述三個標準對每一個建議進行評估(定性和定量)。

  這篇文章概述了我們為提高每個核心頁面指標(Core Web Vitals)的效能而提出的首要建議。

一、LCP

  第一組建議是針對最大內容在可視區域內變得可見的時間(LCP),它是負載效能的衡量標準。

  當今網路上所有站點中的 LCP 只有大約一半達到建議的閾值——所以讓我們從這裡開始。

1)確保可以從 HTML 源中發現 LCP 資源

  根據 HTTP Archive 的 2022 Web Almanac72% 的移動頁面將影象作為 LCP 元素,這意味著對於大多數網站來說,要優化 LCP,需要確保這些影象可以快速載入。

  許多開發人員可能不太清楚的是,載入影象所需的時間只是挑戰的一部分,另一個關鍵部分是影象開始載入之前的時間。

  事實上,在 LCP 元素是影象的頁面中,39% 的影象具有無法從 HTML 檔案源中發現的源 URL。

  換句話說,這些 URL 在標準 HTML 屬性(例如 <img src="..."> 或 <link rel="preload" href="...">)中找不到,而這些屬性可以讓瀏覽器迅速發現它們並立即開始載入。

  如果頁面需要等待 CSS 或 JavaScript 檔案完全下載、解析和處理,然後影象才能開始載入,那麼可能已經太晚了。

  作為一般規則,如果您的 LCP 元素是影象,則影象的 URL 應該始終可以從 HTML 源中找到。 使之成為可能的一些技巧是:

  • 使用具有 src 或 srcset 屬性的 <img> 元素載入影象。
    • 不要使用需要 JavaScript 才能呈現的非標準屬性,如 data-src,因為那樣總是會更慢。 9% 的頁面在 data-src 後面遮蓋了他們的 LCP 影象。
  • 首選伺服器端呈現 (SSR) 而不是使用者端呈現 (CSR)。
    • 因為 SSR 意味著完整的頁面元素(包括影象)存在於 HTML 原始碼中。 CSR 解決方案要求在影象被發現之前執行 JavaScript。
  • 如果你的圖片需要從外部 CSS 或 JS 檔案中參照,你仍然可以通過 <link rel="preload"> 標籤將其包含在 HTML 原始碼中。
    • 請注意,瀏覽器的預載入掃描器無法發現內聯樣式參照的影象,因此即使在 HTML 源中找到它們,在載入其他資源時仍可能會阻止對它們的發現,因此預載入在這些情況下會有所幫助。

   為了幫助你瞭解 LCP 影象是否存在可發現性問題,Lighthouse 將在 10.0 版(預計 2023 年 1 月)中釋出新的審查器

   確保可以從 HTML 源中發現 LCP 資源可以帶來可衡量的改進,並且還可以解鎖額外的機會來確定資源的優先順序,這是我們的下一個建議。

2)確保優先載入 LCP 資源

  確保可以從 HTML 源中發現 LCP 資源是確保 LCP 資源可以及早開始載入的關鍵的第一步,但另一個重要步驟是確保優先載入該資源並且不會排在一堆不太重要的資源後面。

  例如,即使 LCP 影象出現在 <img> 的標準屬性中,但是在它之前有一堆 <script>,那麼就必須在指令碼載入完後,才能載入影象。

  解決此問題的最簡單方法是通過在載入 LCP 影象的 <img> 或 <link> 設定新的 fetchpriority="high" 屬性,向瀏覽器提供哪些資源具有最高優先順序的提示。

  這指示瀏覽器提前載入它,而不是等待這些指令碼完成。

  根據 Web Almanac,只有 0.03% 的符合條件的頁面正在利用這個新的 API,這意味著 Web 上的大多數網站都有很多機會以很少的工作來改進 LCP。

  雖然 fetchpriority 屬性目前僅在基於 Chromium 的瀏覽器中受支援,但此 API 是一種漸進式增強功能,其他瀏覽器會忽略它,因此我們強烈建議開發人員立即使用它。

  對於非 Chromium 瀏覽器,確保 LCP 資源優先於其他資源的唯一方法是在檔案的前面參照它。

  再次使用之前的範例,如果你想確保 LCP 資源優先於那些指令碼資源,你可以新增 <link rel="preload" > 標記在任何這些指令碼之前,或者你可以將這些指令碼移動到 <img> 下面的 <body> 中。

  雖然這可行,但它不如使用 fetchpriority 來得優雅,因此我們希望其他瀏覽器儘快新增支援。

  對 LCP 資源進行優先順序排序的另一個重要方面是確保你不會執行任何導致它被取消優先順序的操作,例如新增 loading="lazy" 屬性。

  今天,10% 的頁面實際上在他們的 LCP 影象上設定了 loading="lazy"。 謹防影象優化解決方案不分青紅皁白地將延遲載入行為應用於所有影象。

  如果他們提供了一種覆蓋該行為的方法,請確保將其用於 LCP 影象。 如果你不確定哪個影象將成為 LCP,請嘗試使用試探法來選擇一個合理的候選影象。

  推遲非關鍵資源是另一種有效提高 LCP 資源相對優先順序的方法。

  例如,不支援使用者介面的指令碼(如分析指令碼或社交小部件)可以安全地推遲到載入事件觸發之後,這就能確保它們不會與其他關鍵資源(如 LCP 資源)競爭網路頻寬了。

  總而言之,你應該遵循這些最佳實踐以確保儘早載入 LCP 資源並以高優先順序載入:

  • 將 fetchpriority="high" 新增到 LCP 影象的 <img> 標記中。
    • 如果 LCP 資源是通過 <link rel="preload"> 標籤載入的,請不要擔心,因為你還可以對其設定 fetchpriority="high"。
  • 永遠不要在 LCP 影象的 <img> 標籤上設定 loading="lazy"。
    • 這樣做會降低影象的優先順序並延遲它開始載入的時間。
  • 儘可能延遲非關鍵資源。
    • 通過將它們移動到檔案的末尾,對影象iframe 使用本機延遲載入,或者通過 JavaScript 非同步載入它們。

3)使用 CDN 優化檔案和資源 TTFB

  前兩個建議側重於確保儘早發現你的 LCP 資源並確定其優先順序,以便它可以立即開始載入。 這個難題的最後一部分是確保初始檔案響應也儘快到達。

  瀏覽器在收到初始 HTML 檔案響應的第一個位元組之前無法載入任何子資源,並且發生得越早,其他一切也可以越早開始發生。

  這段時間稱為首位元組時間 (TTFB),減少 TTFB 的最佳方法是:

  • 在地理位置上儘可能靠近使用者。
  • 快取該內容,以便可以快速再次提供最近請求的內容。

  完成這兩件事的最佳方式是使用 CDNCDN 將你的資源分發到遍佈全球的邊緣伺服器,從而限制了這些資源必須通過線路傳輸到你的使用者的距離。

  CDN 通常還具有細粒度的快取控制,可以根據你站點的需要進行客製化和優化。

  許多開發人員都熟悉使用 CDN 託管靜態資產,但 CDN 也可以快取 HTML 檔案,即使是那些動態生成的檔案。

  根據 Web Almanac,只有 29% 的 HTML 檔案請求是由 CDN 提供的,這意味著網站有很大的機會要求額外的節省。

  設定 CDN 的一些技巧是:

  • 考慮增加快取內容的時間,例如內容總是新鮮的是否真的很重要?或者它可以過時幾分鐘?。
  • 甚至可以考慮無限期地快取內容,然後在您進行更新時清除快取。
  • 探索你是否可以將當前在源伺服器上執行的動態邏輯移動到邊緣計算(Edge Computing)。

  一般來說,任何時候你都可以直接從邊緣提供內容(避免存取你的原始伺服器),這是效能上的勝利。

  即使在你確實必須一路返回到原始伺服器的情況,CDN 通常也會進行優化以更快地完成該過程,因此無論哪種方式都是雙贏。

二、CLS

  下一組建議是針對累積佈局移動時間 (CLS) 的,它是衡量網頁視覺穩定性的指標。

  儘管 CLS 自 2020 年以來在網路上有了很大改進,但仍有約四分之一的網站未達到建議的閾值

1)為從頁面載入的任何內容設定明確的大小

  當現有內容在其他內容完成載入後移動時,通常會發生佈局偏移因此,緩解這種情況的主要方法是儘可能提前預留任何需要的空間。

  修復由未調整大小的影象引起的佈局偏移的最直接方法是顯式設定寬度和高度屬性(或等效的 CSS 屬性)。

  然而,根據 HTTP Archive,72% 的頁面至少有一張未調整尺寸的圖片。

  如果沒有明確的大小,瀏覽器最初將設定預設高度為 0px,並且可能會在最終載入影象並行現尺寸時導致明顯的佈局偏移。

  同樣重要的是要記住,影象並不是 CLS 的唯一影響因素。 佈局偏移可能是由在頁面最初呈現後載入的其他內容引起的,包括第三方廣告或嵌入式視訊。

  aspect-ratio 屬性可以幫助解決這個問題。 這是一個相對較新的 CSS 功能,允許開發人員明確提供影象和非影象元素的寬高比。

  這將允許你設定動態寬度(例如基於螢幕尺寸),並讓瀏覽器自動計算適當的高度,這與它們對具有尺寸的影象所做的方式大致相同。

  有時無法知道動態內容的確切大小,因為它本質上是動態的。 然而,即使你不知道確切的大小,你仍然可以採取措施來降低佈局偏移的嚴重程度。

  設定合理的最小高度幾乎總是比允許瀏覽器對空元素使用預設高度 0px 更好。

  使用最小高度通常也是一個簡單的解決方法,因為它仍然允許容器在需要時增長到最終的內容高度。

2)確保頁面符合 bfcache 的條件

  瀏覽器使用稱為後退/前進快取(簡稱 bfcache)的導航機制,直接從記憶體快照中立即載入瀏覽器歷史記錄中較早或較晚的頁面。

  bfcache 是一項重要的瀏覽器級效能優化,它完全消除了頁面載入期間的佈局變化,對於許多網站來說,這是大部分 CLS 發生的地方。

  儘管如此,仍有大量網站不符合 bfcache 的條件,因此錯過了獲得大量導航的免費 Web 效能優化。

  除非你的頁面正在載入你不想從記憶體中恢復的敏感資訊,否則你需要確保你的頁面符合條件。

  網站所有者應該檢查他們的頁面是否符合 bfcache 的條件,並解決他們不符合的任何原因。

  Chrome 在 DevTools 中已經有一個 bfcache 測試器,今年我們計劃通過執行類似測試的新 Lighthouse 審查器和一個 API 來增強這裡的工具,以在該領域進行測量。

  雖然我們在 CLS 部分中包含了 bfcache,但正如我們目前看到的最大收益一樣,bfcache 通常也會改進其他 Core Web Vitals。

  它是可用於大幅改進頁面導航的眾多即時導航之一。 

3)避免使用誘導佈局的 CSS 動畫和過渡屬性

  佈局變化的另一個常見來源是元素動畫化。 例如,從頂部或底部滑入的橫幅或其他通知橫幅通常是 CLS 的影響因素。

  當這些橫幅將其他內容推開時,這就成了問題,但即使它們沒有,動畫化它們仍然會影響 CLS。

  雖然 HTTP Archive 資料最終不能將動畫與佈局轉換聯絡起來,但資料確實表明,將任何可能影響佈局的 CSS 屬性製成動畫的頁面,其 "良好 "的 CLS 的可能性比整體頁面低15%。

  有些屬性比其他屬性的 CLS 更差例如,動畫頁邊距或邊框寬度的頁面具有「差」的 CLS,幾乎是整體頁面被評估為差的比率的兩倍。

  這也許並不奇怪,因為任何時候你轉換或動畫任何影響佈局的 CSS 屬性,它都會導致佈局偏移,如果這些佈局偏移不在使用者互動的 500 毫秒內,那麼它們將影響 CLS。

  一些開發人員可能會感到驚訝的是,即使在元素超出正常檔案流的情況下也是如此。

  例如動畫頂部或左側的絕對定位元素將導致佈局偏移,即使它們沒有推動其他內容。

  但是,如果不是對頂部或左側進行動畫處理,而是對 transform:translateX() 或 transform:translateY() 進行動畫處理,則不會導致瀏覽器更新頁面佈局,因此不會產生任何佈局變化。

  長期以來,首選可以在瀏覽器的合成器執行緒上更新的 CSS 屬性動畫一直是一種效能最佳實踐,因為它將工作轉移到了 GPU 上並脫離了主執行緒。

  除了作為一般效能最佳實踐之外,它還可以幫助改進 CLS。

  作為一般規則,永遠不要為任何需要瀏覽器更新頁面佈局的 CSS 屬性設定動畫或過渡,除非你是為了響應使用者點選或按鍵(儘管不是懸停)。

  並且儘可能使用 CSS transform 屬性的過渡和動畫。

  Lighthouse 的 Avoid non-composited animations 將在頁面對可能較慢的 CSS 屬性進行動畫處理時發出警告。

三、FID

  我們的最後一組建議是針對首次輸入延遲 (FID) ,它是衡量頁面對使用者互動的響應能力的指標,即使用者第一次與頁面互動到瀏覽器對互動作出響應的時間。

  雖然網路上的大多數網站目前在 FID 上得分都很高,但我們在過去記錄了 FID 指標的缺點,我們相信網站仍有很多機會提高其對使用者互動的整體響應能力。

  我們新的與下一次繪製的互動 (INP) 指標可能是 FID 的繼任者,下面的所有建議同樣適用於 FID 和 INP。

  鑑於網站在 INP 上的表現比 FID ,尤其是在移動裝置上,我們鼓勵開發人員認真考慮這些響應建議,儘管 FID 是「好」的。

1)避免或中斷長時間的任務

  任務是指瀏覽器所做的任何一件不連續的工作。任務包括呈現、佈局、解析以及編譯和執行指令碼。

  當任務變成長任務(即 50 毫秒或更長)時,它們會阻止主執行緒快速響應使用者輸入。

  根據 Web Almanac,有大量證據表明開發人員可以採取更多措施來避免或分解長任務。

  雖然分解長任務可能不像本文中的其他建議那樣省力,但它比本文未提供的其他技術省力。

  雖然你應該始終努力在 JavaScript 中做盡可能少的工作,但你可以通過將長任務分解為更小的任務來幫助主執行緒,以便渲染更新和其他使用者互動可以更快地發生。 

  另一種選擇是考慮使用 isInputPendingScheduler API

  isInputPending 是一個返回布林值的函數,該值指示使用者輸入是否待處理。 如果它返回 true,就可以中斷 JavaScript 的執行,讓瀏覽器可以去處理那些使用者輸入。

  Scheduler API 是一種更高階的方法,它允許你根據優先順序系統安排工作,該系統考慮到正在完成的工作是使用者可見的還是後臺的。

  通過分解長任務,你可以讓瀏覽器有更多機會來處理關鍵的使用者可見工作,例如處理互動和任何由此產生的渲染更新。

2)避免不必要的 JavaScript

  毫無疑問:當今網站傳輸的 JavaScript 比以往任何時候都多,而且這種趨勢看起來不會很快改變。

  當你傳送過多的 JavaScript 時,你正在建立一個任務競爭主執行緒注意力的環境。 這肯定會影響你網站的響應能力,尤其是在關鍵的啟動期間。

  然而,這並不是一個無法解決的問題。 你確實有一些選擇:

  • 使用 Chrome DevTools 中的覆蓋工具來查詢網站資源中未使用的程式碼。
    • 通過減少啟動期間所需資源的大小,可以確保網站花費更少的時間來解析和編譯程式碼,從而帶來更流暢的初始使用者體驗。
  • 通過程式碼拆分將這些程式碼移動到單獨的包中。
    • 有時,使用覆蓋工具找到的未使用程式碼會被標記為「未使用」,因為它在啟動期間未被執行,但對於將來的某些功能來說仍然是必需的。
  • 如果你使用的是標籤管理器,請務必定期檢查你的標籤以確保它們經過優化,或者即使它們仍在使用中也是如此。
    • 可以清除帶有未使用程式碼的舊標籤,以使你的標籤管理器的 JavaScript 更小、更高效。

3)避免大型渲染更新

  JavaScript 並不是唯一可以影響網站響應能力的因素。

  渲染本身就可能是一種昂貴的工作——當發生大量渲染更新時,它們可能會干擾網站響應使用者輸入的能力。

  優化渲染工作並不是一個簡單的過程,它通常取決於你想要實現的目標。

  即便如此,你還是可以做一些事情來確保你的渲染更新是合理的,並且不會蔓延到長時間的任務中:

  • 避免使用 requestAnimationFrame() 進行任何非視覺工作。
    • requestAnimationFrame() 呼叫在事件迴圈的渲染階段處理,如果在此步驟中完成過多工作,渲染更新可能會延遲。
  • 保持 DOM 小尺寸
    • DOM 大小和佈局工作的強度相關。當渲染器必須為非常大的 DOM 更新佈局時,重新計算其佈局所需的工作會顯著增加。
  • 使用 CSS containment
    • CSS containment 依賴於 CSS contain 屬性,它向瀏覽器發出指令,說明如何為 contain 屬性設定的容器進行佈局工作,甚至包括將佈局範圍和渲染隔離到 DOM 中的特定根目錄。
    • 這並不總是一個簡單的過程,但通過隔離包含複雜佈局的區域,可以避免為它們進行不必要的佈局和渲染工作。

 

  如果你想了解更多的優化建議,請檢視以下列表: