網頁功能:
content-visibility
當瀏覽器未算繪元件時,請暫停繁重的背景工作,以節省系統資源和電池電力。
總覽
content-visibility: auto 屬性可讓瀏覽器略過檢視區外元素的算繪計算。當瀏覽器決定略過或繼續轉譯元素時,會對該元素觸發 contentvisibilityautostatechange 事件。
監聽這個事件,即可在不需要時暫停耗費資源的操作,例如 <canvas> 動畫、WebGL 轉譯或高頻率 WebSocket 資料輪詢,並在瀏覽器準備顯示內容時及時恢復。
contentvisibilityautostatechange (與 IntersectionObserver比較)
請務必瞭解各 API 的使用時機:
- 使用
IntersectionObserver處理應用程式邏輯,該邏輯與可視區域中元素的確切視覺可見度相關 (例如延遲載入資料、無限捲動觸發條件)。 - 使用
contentvisibilityautostatechange處理需要大量算繪的工作 (例如複雜的畫布更新或大量 DOM 變動)。這個事件與瀏覽器的內部轉譯生命週期直接相關。瀏覽器通常會在元素實際顯示在畫面上之前,就開始轉譯元素 (預先轉譯邊界)。這個事件會通知您何時發生這種情況,確保內容已準備好顯示。
導入作業
1. 套用 CSS 內容可見度
在大型容器上設定 content-visibility: auto,並提供預留位置大小,避免捲軸跳動。
.heavy-component {
/* Defer rendering work when off-screen */
content-visibility: auto;
/* Mandatory: Provide a placeholder size to prevent layouts shifts.
- '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.
- 'none' tells the browser not to apply any intrinsic width to this element.
It can be used for either the height or the width value.
- '500px' 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 none auto 500px;
}
2. 監聽狀態變更
為 contentvisibilityautostatechange 新增事件監聽器,以便暫停或繼續背景工作。
const component = document.querySelector('.heavy-component');
// Option 1: Direct listener (recommended)
component.addEventListener('contentvisibilityautostatechange', (event) => {
if (event.skipped) {
// The browser skipped rendering this content.
// DO NOT perform heavy mutations or animation loops here.
stopSimulation();
pauseWebSocketPolling();
} else {
// The browser is about to render the content.
// Resume your work so it is ready when visible.
startSimulation();
resumeWebSocketPolling();
}
});
// Option 2: Capturing listener for event delegation
document.addEventListener('contentvisibilityautostatechange', (event) => {
if (event.target.matches('.heavy-component')) {
if (event.skipped) {
stopSimulation();
} else {
startSimulation();
}
}
}, { capture: true });
備用策略
content-visibility 屬性和相關聯的 contentvisibilityautostatechange 事件是漸進增強。在不支援這類 Cookie 的瀏覽器中:
- 系統會忽略 CSS 屬性,並正常顯示內容。
- 事件不會觸發,因此背景工作會繼續正常執行,不會進行最佳化。
如果必須支援在舊版瀏覽器上暫停工作,可以改用 IntersectionObserver 做為粗略近似值。這也有助於節省舊裝置的電池和 CPU。
// Fallback using IntersectionObserver for older browsers
const target = document.getElementById('target-container');
// Check if content-visibility is supported
const isSupported = 'contentVisibility' in document.documentElement.style;
if (!isSupported) {
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
// The element is close to the screen. Start work!
startSimulation();
} else {
// The element is far away. Pause work!
stopSimulation();
}
});
}, {
// Use rootMargin to start rendering before it hits the screen
rootMargin: '200px'
});
observer.observe(target);
}