透過狀態快取加快 SPA 檢視畫面轉換

網頁功能: content-visibility

快取閒置檢視畫面的算繪狀態,而非刪除,以便在單頁應用程式 (SPA) 的檢視畫面之間即時導覽。

總覽

一般來說,當使用者在 SPA 的分頁或檢視畫面之間切換時,開發人員會刪除舊的檢視畫面,或使用 display: none 隱藏。這兩種方法都要求瀏覽器在使用者返回該檢視畫面時,重新建立或重新計算完整版面配置和繪製。

在非使用中的檢視畫面上使用 content-visibility: hidden,瀏覽器會從版面配置流程中移除元素內容,並停止繪製,但會將快取的轉譯狀態「保留」在記憶體中。使用者切換回來時,檢視畫面會立即還原。

CPU 與 RAM 的權衡

雖然這種做法能大幅提升效能,但您必須謹慎權衡以下取捨:

  • CPU 節省量:大幅減少。瀏覽器會完全略過隱藏檢視畫面的版面配置和繪製階段。
  • RAM 成本:高。瀏覽器會將隱藏檢視畫面的所有 DOM 節點、事件監聽器和狀態保留在記憶體中。

當這種權衡變得危險時

  • 建議:如果應用程式較簡單,且檢視畫面數量較少且可預測 (例如 3 到 5 個分頁介面),請使用這項策略。
  • 請勿在高度動態的應用程式中,無條件快取每個檢視畫面,因為這類應用程式會產生數十個不重複報表,或使用無限動態路徑。否則最終會導致記憶體嚴重膨脹,並可能造成低階裝置上的瀏覽器異常終止。
  • 必要:如果應用程式高度動態,您「必須」實作淘汰策略 (例如最近最少使用快取),在達到記憶體門檻時刪除舊檢視畫面。

導入作業

1. 設定檢視容器

在目前未啟用的檢視畫面上設定 content-visibility: hidden。

.spa-view.inactive {
  /* MANDATORY: Use hidden to cache the rendering state of inactive views */
  content-visibility: hidden;
  
  /* Optional: Prevent hidden views from taking up physical space in layout flow */
  position: absolute;
}

2. 管理專注模式

切換檢視畫面時,請務必正確管理鍵盤焦點,確保無障礙功能正常運作。

function switchToView(viewId) {
  // Hide all views
  document.querySelectorAll('.spa-view').forEach(view => {
    view.classList.add('inactive');
    view.setAttribute('aria-hidden', 'true');
  });
  
  // Show the target view
  const activeView = document.getElementById(viewId);
  activeView.classList.remove('inactive');
  activeView.setAttribute('aria-hidden', 'false');
  
  // MANDATORY: Move focus to the new view to ensure a logical tab-order
  activeView.focus();
}

備用策略

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

  • 系統會忽略該屬性。
  • 為避免備用瀏覽器同時顯示所有檢視畫面,請在 CSS 中為 display: none 提供備用:
@supports not (content-visibility: hidden) {
  .spa-view.inactive {
    display: none;
  }
}