जब ब्राउज़र किसी कॉम्पोनेंट को रेंडर न कर रहा हो, तब बैकग्राउंड में चल रहे ज़्यादा रिसॉर्स इस्तेमाल करने वाले टास्क को रोकें. इससे सिस्टम के रिसॉर्स और बैटरी लाइफ़ को बचाया जा सकता है.
खास जानकारी
content-visibility: auto प्रॉपर्टी की मदद से, ब्राउज़र उन एलिमेंट के लिए रेंडरिंग कैलकुलेशन को स्किप कर सकता है जो व्यूपोर्ट से काफ़ी बाहर हैं. जब ब्राउज़र किसी एलिमेंट को रेंडर करने से स्किप करने या उसे फिर से रेंडर करने का फ़ैसला लेता है, तो वह उस एलिमेंट पर contentvisibilityautostatechange इवेंट को ट्रिगर करता है.
इस इवेंट को सुनकर, ज़रूरत न होने पर <canvas> ऐनिमेशन, WebGL रेंडरिंग या ज़्यादा फ़्रीक्वेंसी वाले WebSocket डेटा पोलिंग जैसे महंगे ऑपरेशन रोके जा सकते हैं. साथ ही, ब्राउज़र के कॉन्टेंट दिखाने के लिए तैयार होने पर, उन्हें तुरंत फिर से शुरू किया जा सकता है.
contentvisibilityautostatechange बनाम IntersectionObserver
यह समझना ज़रूरी है कि किस एपीआई का इस्तेमाल कब करना चाहिए:
- व्यूपोर्ट में किसी एलिमेंट के विज़ुअल तौर पर दिखने से जुड़े ऐप्लिकेशन लॉजिक के लिए
IntersectionObserverका इस्तेमाल करें. उदाहरण के लिए, लेज़ी-लोडिंग डेटा, इनफ़ाइनाइट स्क्रोल ट्रिगर. contentvisibilityautostatechangeका इस्तेमाल, रेंडरिंग से जुड़े ज़्यादा काम के लिए करें. जैसे, जटिल कैनवस अपडेट या ज़्यादा डीओएम म्यूटेशन. यह इवेंट, सीधे तौर पर ब्राउज़र के इंटरनल रेंडरिंग लाइफ़साइकल से जुड़ा होता है. ब्राउज़र अक्सर किसी एलिमेंट को स्क्रीन पर दिखने से पहले ही रेंडर करना शुरू कर देता है. इसे प्री-रेंडर मार्जिन कहते हैं. यह इवेंट आपको बताता है कि ऐसा कब होता है. इससे यह पक्का होता है कि आपका कॉन्टेंट देखने के लिए तैयार है.
लागू करना
1. सीएसएस कॉन्टेंट विज़िबिलिटी लागू करना
ज़्यादा डेटा वाले कंटेनर पर 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 इवेंट, प्रोग्रेसिव एनहैंसमेंट हैं. उन ब्राउज़र में जिनमें ये काम नहीं करते:
- सीएसएस प्रॉपर्टी को अनदेखा कर दिया जाता है और कॉन्टेंट सामान्य तरीके से रेंडर होता है.
- इवेंट कभी ट्रिगर नहीं होता. इसलिए, बैकग्राउंड टास्क सामान्य तरीके से चलते रहेंगे. हालांकि, इन्हें ऑप्टिमाइज़ नहीं किया जाएगा.
अगर आपको पुराने ब्राउज़र पर टास्क रोकने की सुविधा देनी है, तो अनुमान के तौर पर IntersectionObserver का इस्तेमाल किया जा सकता है. इससे पुराने डिवाइसों पर भी बैटरी और सीपीयू की बचत होती है.
// 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);
}