content-visibility:可提升算繪成效的全新 CSS 資源

略過畫面外內容的顯示作業,縮短初始載入時間。

Vladimir Levin
Vladimir Levin

在 Chromium 85 版中推出的 content-visibility 屬性,可能是最能影響網頁載入效能的全新 CSS 屬性之一。content-visibility 可讓使用者代理程式略過元素的轉譯工作,包括版面配置和繪製工作,直到需要執行為止。由於系統會略過轉譯作業,如果您大部分的內容位於畫面外,使用 content-visibility 屬性可以大幅加快初始使用者的載入速度。這也有助於提升與畫面上內容的互動速度。效果好吃。

以圖表代表網路結果的圖表
在我們的文章示範中,將 content-visibility: auto 套用至分塊內容區域,可使初始載入作業效能提升 7 倍。繼續閱讀以瞭解詳情。

瀏覽器支援

瀏覽器支援

  • 85
  • 85
  • 124

來源

content-visibility 依賴 CSS 內含項目規格中的基本項目。雖然 Chromium 85 目前只支援 content-visibility (且在 Firefox 中應視為「價值原型」),但大部分新型瀏覽器也支援「包含」規格。

CSS 包含

CSS 遏製作業的關鍵和主要目標,是藉由為網頁其餘部分提供可預測的 DOM 子樹狀結構,實現網頁內容的轉譯效能改善。

基本上,開發人員可以告訴瀏覽器網頁上有哪些部分封裝為一組內容,讓瀏覽器可以瞭解內容,而不需要考慮子樹狀結構以外的狀態。瞭解哪些內容部分 (子樹狀結構) 包含獨立內容,讓瀏覽器能夠針對轉譯網頁做出最佳化決策。

CSS 包含項目有四種類型,每種類型都是 contain CSS 屬性的潛在值,可用以空格分隔的值清單合併。

  • size:元素的大小包含,可確保元素方塊可以延伸,而無需檢查其子系。也就是說,如果我們只需要元素大小,就可能略過子系的版面配置。
  • layout:版面配置包含表示子係不會影響頁面上其他方塊的外部版面配置。這可讓我們可能略過子系的版面配置,如果我們要只配置其他方塊。
  • style:樣式包含可確保對子係以外有影響的屬性,不會逸出元素 (例如計數器)。這樣如果我們只想在其他元素上計算樣式,就可能略過子系的樣式運算。
  • paint: Paint 包含可確保所含方塊的子係不會在其邊界外顯示。元素完全不會溢位,如果元素在畫面外或未顯示時,就不會顯示其子系。如此一來,當元素不在畫面外時,我們就可以略過子系繪製作業。

使用 content-visibility 略過轉譯工作

由於瀏覽器最佳化只能在指定適當的組合時啟動,因此很難確定要使用哪些包含值。您可以嘗試各種值,看看哪種效果最佳,也可以使用另一個名為 content-visibility 的 CSS 屬性自動套用所需的包含。content-visibility 可確保瀏覽器最大限度地提升瀏覽器效能。

內容瀏覽權限屬性可接受多個值,但 auto 是立即改善效能的屬性值。具有 content-visibility: auto 的元素會取得 layoutstylepaint 控制。如果元素位於畫面外 (且與使用者無關的元素是子樹狀結構中具有焦點或已選取的項目),則也會取得 size 包含 (且會停止繪製命中測試)。

使用這項功能,簡單來說,如果元素在畫面外顯示,就不會轉譯其子系。瀏覽器在不考慮元素任何內容的情況下,會決定元素的大小,並停止該元素的大小。系統會略過大部分的算繪作業,例如元素子樹狀結構的樣式和版面配置。

當元素接近可視區域時,瀏覽器就不會再新增 size 包含項目,並開始繪製並測試元素的內容。如此一來,轉譯工作就能及時完成,供使用者查看。

無障礙注意事項

content-visibility: auto 的其中一項功能是,在文件物件模型中仍可使用畫面外內容,因此無障礙功能樹狀結構 (與 visibility: hidden 不同) 除外。這表示使用者可以在網頁上搜尋及前往內容,不必等待載入或犧牲算繪效能。

不過,也有缺點,就是具備樣式功能 (例如 display: nonevisibility: hidden) 的地標元素也會出現在螢幕外時,無障礙功能樹狀結構中,因為瀏覽器必須等這些樣式進入可視區域後,才會轉譯這些樣式。為避免在無障礙樹狀結構中顯示這些內容,請務必一併新增 aria-hidden="true"

範例:旅遊網誌

在本範例中,我們可以在右側基準旅遊網誌,並將 content-visibility: auto 套用至左側的區塊區塊。結果會顯示網頁初次載入時,轉譯時間從 232 毫秒30 毫秒

旅遊網誌通常包含一組內含幾張圖片的故事,以及一些描述性文字。以下是一般瀏覽器中前往旅遊網誌時會發生的情況:

  1. 系統會從網路下載頁面中的部分內容,以及任何必要資源。
  2. 瀏覽器樣式及排列所有網頁內容,而不考慮是否對使用者顯示內容。
  3. 瀏覽器會返回步驟 1,直到所有頁面和資源都下載完成。

在步驟 2 中,瀏覽器會處理所有內容,檢查可能已變更的內容。這個面板會更新任何新元素的樣式和版面配置,以及因更新而變動的元素。這表示轉譯作業可以正常運作。這可能需要時間。

旅遊網誌的螢幕截圖。
旅遊網誌範例。請參閱 Codepen 的示範

現在請思考如果在網誌中的每則報導都加上 content-visibility: auto,會發生什麼事。一般迴圈也是如此:瀏覽器下載並轉譯網頁的區塊。然而,差別在於步驟 2 執行了大量工作。

如果採用內容可見度,系統就會對使用者目前可見 (也就是在畫面上顯示) 的所有內容設定樣式和版面配置。不過,瀏覽器在處理完全離開畫面外的故事時,會略過算繪工作,只設定元素方塊的樣式及版面配置。

這個頁面的載入效能,會如同內含全螢幕故事畫面和每個螢幕外故事的空白方塊一樣。這個做法的成效更好,且轉譯成本的預期可減少 50% 以上。在本例中,我們發現轉譯時間從 232 毫秒增加至 30 毫秒。效能提升 7 倍

你需要採取哪些工作才能獲得這些好處?首先,我們將內容分為多個部分:

註解螢幕截圖:使用 CSS 類別將內容切割為不同區段。
為了接收 content-visibility: auto,將內容分割為多個區段的範例,並套用 story 類別。請參閱 Codepen 的示範

接著,將下列樣式規則套用到這些部分:

.story {
  content-visibility: auto;
  contain-intrinsic-size: 1000px; /* Explained in the next section. */
}

使用 contain-intrinsic-size 指定元素的自然大小

為了發揮 content-visibility 的潛在效益,瀏覽器需要套用大小限制,確保內容的轉譯結果以任何方式影響元素大小。這表示該元素會像為空白一樣版面配置。如果元素未指定一般區塊版面配置中的高度,則其高度為 0。

這可能不理想,因為捲軸的大小會改變,因為這些故事的高度不是零。

幸好,CSS 提供了另一個 contain-intrinsic-size 屬性,該屬性可有效指定元素的自然大小 (如果元素會受到大小遏制影響)。在本範例中,我們將設定值設為 1000px,做為區段高度和寬度的預估值。

這表示此版面配置會以「內建大小」維度的單一子項一樣版面配置,確保未調整大小的 div 仍佔用空間。contain-intrinsic-size 為預留位置大小,取代顯示的內容。

在 Chromium 98 以上版本中,contain-intrinsic-size 有一個新的 auto 關鍵字。如果有指定,瀏覽器會記住上次算繪的大小 (如有),並使用該大小而非開發人員提供的預留位置大小。舉例來說,如果您指定 contain-intrinsic-size: auto 300px,元素一開始每個尺寸都會設定 300px 內建尺寸,但元素內容算繪後,就會保留轉譯的內建函式大小。系統也會記住所有後續的顯示大小變更。實際上,這表示如果您套用 content-visibility: auto 的捲動元素,然後將其捲動回螢幕,它會自動維持其理想的寬度和高度,但不會還原為預留位置大小。這項功能對無限捲動器特別實用,現在可在使用者瀏覽頁面時,自動改善大小估計值。

使用 content-visibility: hidden 隱藏內容

無論內容是否在畫面上顯示,都要保持未算繪狀態,同時利用快取轉譯狀態的優點嗎?輸入:content-visibility: hidden

content-visibility: auto 在螢幕外執行時,content-visibility: hidden 屬性可授予未算繪內容和快取轉譯狀態的所有優點。不過,與 auto 不同,它不會自動開始在螢幕上算繪。

這樣做可讓您進一步掌控相關設定,以便隱藏元素內容,之後再快速取消隱藏。

和其他隱藏元素內容的常見方式進行比較:

  • display: none:隱藏元素並刪除其轉譯狀態。這表示取消隱藏元素的費用,與轉譯內容相同的新元素的費用一樣。
  • visibility: hidden:隱藏元素並保留其算繪狀態。這項操作並不能真的將元素從文件中移除,因為該元素 (及其子樹狀結構) 仍會佔用頁面上的幾何空間,使用者仍可點選。也能隨時更新算繪狀態,即使隱藏也一樣。

另一方面,content-visibility: hidden 會隱藏元素,同時保留其轉譯狀態,因此如果有任何需要變更,只會在元素再次顯示時才會發生 (即移除 content-visibility: hidden 屬性)。

實作進階虛擬捲動器及評估版面配置時,為 content-visibility: hidden 有一些絕佳用途。非常適合單頁應用程式 (SPA)閒置的應用程式檢視畫面可以在 DOM 中套用 content-visibility: hidden,避免顯示,但維持其快取狀態。如此一來,當檢視畫面再次進入有效狀態時,檢視畫面就能快速算繪。

對下一個顯示效果的影響 (INP)

INP 指標評估的是網頁能否穩定回應使用者輸入的內容。在主執行緒上發生大量工作 (包括轉譯工作) 時,回應速度可能會受到影響。

只要可以減少任何特定網頁的轉譯工作,主執行緒就能更快地回應使用者輸入內容。這包括轉譯工作,以及在適當的情況下使用 content-visiblity CSS 屬性可能會減少轉譯工作,特別是在啟動期間,大部分的算繪和版面配置工作都已完成。

減少轉譯工作會對 INP 造成直接影響。如果使用者嘗試與正確使用 content-visibility 屬性的網頁互動,以便延遲版面配置和畫面外元素轉譯作業,主執行緒有機會回應使用者可見的重要工作。這在某些情況下可以改善網頁的 INP。

結論

content-visibility 和 CSS 包含規格規格,表示您的 CSS 檔案即將顯示一些令人期待的效能提升。如要進一步瞭解這些屬性,請參閱: