最佳化複雜版面配置中的互動

網頁功能: content-visibility

在看板或大型資料網格等複雜的多欄版面配置中,拖放或大量變更時,仍能維持高影格率 (60 FPS) 並消除互動延遲。

總覽

在複雜的版面配置中,對單一項目進行微幅變更 (例如拖曳資訊卡或編輯儲存格),可能會觸發樣式和版面配置計算的連鎖反應,迫使瀏覽器重排整個頁面。這會導致影格遺失,以及 Interaction to Next Paint (INP) 延遲時間過長。

將 content-visibility: auto 套用至獨立的版面配置區域 (例如看板中的資料欄),即可隔離轉譯作業。

畫面元素的機制

請務必瞭解 content-visibility: auto 如何讓「已顯示在螢幕上」的元素受益:

  • 對於可見元素,瀏覽器「不會」略過算繪。
  • 相反地,成效提升完全來自屬性自動強制執行的 CSS 限制 (即版面配置、樣式和繪製)。
  • 這個容器會做為邊界。如果套用 containment 的容器內發生變動,瀏覽器會知道這些變更不會影響該容器外元素的幾何圖形或樣式。網頁重排會獨立進行,避免重新計算全域版面配置。

導入作業

1. 找出圍堵區域

將 content-visibility: auto 套用至大型、獨立的容器,代表獨立的版面配置單元 (例如格線欄、面板清單)。

.board-column {
  /* Apply containment boundaries */
  content-visibility: auto;
  
  /* Mandatory: Provide a placeholder size to prevent layouts shifts.
     For a vertical column, define a reasonable width and height. 
     - 'auto' is optional and enables the browser to remember the actual size
       once rendered. It must be paired with a <length> value to be used for
       the first render.
     - '300px' is the estimated width of this element. This can be any valid
      CSS <length> value. Replace it with the expected width of your
      component.
     - '800px' is the estimated height of this element. This can be any valid
      CSS <length> value. Replace it with the expected height of your
      component.
   */
  contain-intrinsic-size: auto 300px auto 800px;
}

2. 管理互動

確保欄內發生的互動能受益於容器。

// Example: Drag and drop item movement
function moveItemToColumn(itemId, columnId) {
  const item = document.getElementById(itemId);
  const column = document.getElementById(columnId);
  
  // The browser will only reflow this specific column, 
  // not the entire board layout!
  column.appendChild(item);
}

備用策略

屬性會正常降級。在不支援的瀏覽器中:

  • 系統會忽略該屬性,且變動會導致標準全域重排。
  • 如要在舊版瀏覽器中達到類似的隔離效果,可以改為手動套用限制:
@supports not (content-visibility: auto) {
  .board-column {
    /* Manual fallback for containment */
    contain: layout style paint;
  }
}