रिग्रेशन का पता लगाने के लिए, प्रोडक्शन में अपने वेब पेज की मेमोरी के इस्तेमाल को मेज़र करने का तरीका जानें.
ब्राउज़र, वेब पेजों की मेमोरी को अपने-आप मैनेज करते हैं. जब भी कोई वेब पेज कोई ऑब्जेक्ट बनाता है, तो ब्राउज़र ऑब्जेक्ट को सेव करने के लिए, "अंडर द हुड" मेमोरी का एक हिस्सा असाइन करता है. मेमोरी एक सीमित संसाधन है. इसलिए, ब्राउज़र गार्बेज कलेक्शन करता है. इससे यह पता चलता है कि किसी ऑब्जेक्ट की ज़रूरत कब नहीं है और मेमोरी के उस हिस्से को खाली किया जा सकता है.
हालांकि, यह पता लगाने की प्रोसेस पूरी तरह से सटीक नहीं होती. एलन ट्यूरिंग की हॉल्टिंग प्रॉब्लम से यह साबित हुआ है कि पूरी तरह से सटीक तरीके से पता लगाना मुमकिन नहीं है. इसलिए, ब्राउज़र "किसी ऑब्जेक्ट की ज़रूरत है" के बजाय "किसी ऑब्जेक्ट को ऐक्सेस किया जा सकता है" का इस्तेमाल करते हैं. अगर वेब पेज, अपने वैरिएबल और अन्य ऐक्सेस किए जा सकने वाले ऑब्जेक्ट के फ़ील्ड के ज़रिए किसी ऑब्जेक्ट तक नहीं पहुंच सकता, तो ब्राउज़र उस ऑब्जेक्ट को सुरक्षित तरीके से वापस पा सकता है. इन दोनों के बीच के अंतर की वजह से मेमोरी लीक होती है. इसे यहां दिए गए उदाहरण में दिखाया गया है.
const object = {a: new Array(1000), b: new Array(2000)};
setInterval(() => console.log(object.a), 1000);
यहां बड़े ऐरे b की अब ज़रूरत नहीं है. हालांकि, ब्राउज़र इसे वापस नहीं लेता, क्योंकि यह अब भी कॉलबैक में object.b के ज़रिए ऐक्सेस किया जा सकता है. इस वजह से, बड़े ऐरे की मेमोरी लीक हो जाती है.
वेब पर मेमोरी लीक की समस्या आम है. इस स्टडी से पता चलता है कि. इवेंट लिसनर को अनरजिस्टर करना भूल जाने, गलती से किसी iframe से ऑब्जेक्ट कैप्चर करने, वर्कर को बंद न करने, ऐरे में ऑब्जेक्ट इकट्ठा करने वगैरह से मेमोरी लीक हो सकती है. अगर किसी वेब पेज में मेमोरी लीक होती है, तो समय के साथ उसकी मेमोरी का इस्तेमाल बढ़ता जाता है. साथ ही, वह वेब पेज लोगों को धीमा और बड़ा दिखता है.
इस समस्या को हल करने का पहला चरण, इसका आकलन करना है. नए performance.measureUserAgentSpecificMemory() एपीआई की मदद से डेवलपर, प्रोडक्शन में अपने वेब पेजों के मेमोरी इस्तेमाल को मेज़र कर सकते हैं. इससे वे मेमोरी लीक का पता लगा सकते हैं जो लोकल टेस्टिंग के दौरान नहीं मिल पाती हैं.
performance.measureUserAgentSpecificMemory(), लेगसी performance.memory API से किस तरह अलग है?
अगर आपको मौजूदा नॉन-स्टैंडर्ड performance.memory एपीआई के बारे में जानकारी है, तो आपको यह लग सकता है कि नया एपीआई इससे किस तरह अलग है. इनके बीच मुख्य अंतर यह है कि पुराना एपीआई, JavaScript हीप का साइज़ दिखाता है. वहीं, नया एपीआई वेब पेज के लिए इस्तेमाल की गई मेमोरी का अनुमान लगाता है. यह अंतर तब अहम हो जाता है, जब Chrome एक ही हीप को कई वेब पेजों या एक ही वेब पेज के कई इंस्टेंस के साथ शेयर करता है. ऐसे मामलों में, पुराने एपीआई का नतीजा गलत हो सकता है. पुराने एपीआई को लागू करने से जुड़ी खास शर्तों, जैसे कि "हीप" के हिसाब से तय किया जाता है. इसलिए, इसे स्टैंडर्ड बनाना मुश्किल है.
एक और अंतर यह है कि नया एपीआई, गार्बेज कलेक्शन के दौरान मेमोरी मेज़रमेंट करता है. इससे नतीजों में मौजूद नॉइज़ कम हो जाती है. हालांकि, नतीजे मिलने में कुछ समय लग सकता है. ध्यान दें कि अन्य ब्राउज़र, कचरा इकट्ठा करने की सुविधा पर भरोसा किए बिना नए एपीआई को लागू करने का फ़ैसला ले सकते हैं.
इस्तेमाल के सुझाए गए उदाहरण
किसी वेब पेज की मेमोरी का इस्तेमाल, इवेंट के समय, उपयोगकर्ता की कार्रवाइयों, और गार्बेज कलेक्शन पर निर्भर करता है. इसलिए, मेमोरी मेज़रमेंट एपीआई का इस्तेमाल प्रोडक्शन से मेमोरी के इस्तेमाल का डेटा इकट्ठा करने के लिए किया जाता है. अलग-अलग कॉल के नतीजे कम मददगार होते हैं. इस्तेमाल के उदाहरण:
- वेब पेज के नए वर्शन को रोल आउट करने के दौरान रिग्रेशन का पता लगाना, ताकि मेमोरी लीक की नई समस्याओं का पता लगाया जा सके.
- नई सुविधा की A/B टेस्टिंग की जाती है, ताकि मेमोरी पर पड़ने वाले इसके असर का आकलन किया जा सके और मेमोरी लीक का पता लगाया जा सके.
- मेमोरी के इस्तेमाल और सेशन कितनी देर चला, इसके बीच संबंध का पता लगाकर, यह पुष्टि करना कि मेमोरी लीक हो रही है या नहीं.
- मेमोरी के इस्तेमाल का लोगों की मेट्रिक से संबंध जोड़कर, मेमोरी के इस्तेमाल के कुल असर को समझना.
वेबसाइट का अलग-अलग ब्राउज़र पर चलना
फ़िलहाल, यह एपीआई सिर्फ़ Chromium पर आधारित ब्राउज़र में काम करता है. यह Chrome 89 से शुरू होता है. एपीआई का नतीजा, लागू करने के तरीके पर काफ़ी हद तक निर्भर करता है. ऐसा इसलिए, क्योंकि ब्राउज़र में ऑब्जेक्ट को मेमोरी में दिखाने के अलग-अलग तरीके होते हैं. साथ ही, मेमोरी के इस्तेमाल का अनुमान लगाने के अलग-अलग तरीके होते हैं. अगर मेमोरी के सभी हिस्सों का हिसाब रखना बहुत महंगा या मुश्किल है, तो ब्राउज़र कुछ हिस्सों को हिसाब से बाहर रख सकते हैं. इसलिए, अलग-अलग ब्राउज़र के नतीजों की तुलना नहीं की जा सकती. एक ही ब्राउज़र के नतीजों की तुलना करना ही सही होता है.
performance.measureUserAgentSpecificMemory() का इस्तेमाल करना
सुविधा का पता लगाना
अगर एक्ज़ीक्यूशन एनवायरमेंट, क्रॉस-ऑरिजिन से जुड़ी जानकारी के लीक होने से रोकने के लिए सुरक्षा से जुड़ी ज़रूरी शर्तों को पूरा नहीं करता है, तो performance.measureUserAgentSpecificMemory फ़ंक्शन उपलब्ध नहीं होगा या SecurityError की वजह से काम नहीं करेगा.
यह क्रॉस-ऑरिजिन आइसोलेशन पर निर्भर करता है. वेब पेज, COOP+COEP हेडर सेट करके इसे चालू कर सकता है.
रनटाइम के दौरान, सहायता का पता लगाया जा सकता है:
if (!window.crossOriginIsolated) {
console.log('performance.measureUserAgentSpecificMemory() is only available in cross-origin-isolated pages');
} else if (!performance.measureUserAgentSpecificMemory) {
console.log('performance.measureUserAgentSpecificMemory() is not available in this browser');
} else {
let result;
try {
result = await performance.measureUserAgentSpecificMemory();
} catch (error) {
if (error instanceof DOMException && error.name === 'SecurityError') {
console.log('The context is not secure.');
} else {
throw error;
}
}
console.log(result);
}
लोकल टेस्टिंग
Chrome, गार्बेज कलेक्शन के दौरान मेमोरी का आकलन करता है. इसका मतलब है कि एपीआई, नतीजे के प्रॉमिस को तुरंत पूरा नहीं करता. इसके बजाय, यह अगले गार्बेज कलेक्शन का इंतज़ार करता है.
एपीआई को कॉल करने पर, कुछ समय के बाद गार्बेज कलेक्शन शुरू हो जाता है. फ़िलहाल, यह समय 20 सेकंड पर सेट है. हालांकि, यह इससे पहले भी शुरू हो सकता है. --enable-blink-features='ForceEagerMeasureMemory' कमांड-लाइन फ़्लैग के साथ Chrome शुरू करने पर, टाइम आउट की अवधि कम होकर शून्य हो जाती है. यह स्थानीय डीबग और टेस्टिंग के लिए फ़ायदेमंद है.
उदाहरण
हमारा सुझाव है कि एपीआई का इस्तेमाल, ग्लोबल मेमोरी मॉनिटर को तय करने के लिए किया जाए. यह पूरे वेब पेज की मेमोरी के इस्तेमाल का सैंपल लेता है और नतीजों को सर्वर पर भेजता है, ताकि उन्हें इकट्ठा करके उनका विश्लेषण किया जा सके. सबसे आसान तरीका यह है कि समय-समय पर सैंपल लिया जाए. उदाहरण के लिए, हर M मिनट में. हालांकि, इससे डेटा में खामी आ सकती है, क्योंकि सैंपल के बीच मेमोरी पीक हो सकती है.
यहां दिए गए उदाहरण में, पॉइसन प्रोसेस का इस्तेमाल करके, मेमोरी को बिना किसी पूर्वाग्रह के मेज़र करने का तरीका बताया गया है. इससे यह पक्का किया जाता है कि सैंपल, किसी भी समय पर बराबर संभावना के साथ दिखें (डेमो, सोर्स).
सबसे पहले, एक ऐसा फ़ंक्शन तय करें जो setTimeout() का इस्तेमाल करके, मेमोरी के अगले मेज़रमेंट को शेड्यूल करता हो. इसमें इंटरवल को रैंडमाइज़ किया जाता है.
function scheduleMeasurement() {
// Check measurement API is available.
if (!window.crossOriginIsolated) {
console.log('performance.measureUserAgentSpecificMemory() is only available in cross-origin-isolated pages');
console.log('See https://web.dev/coop-coep/ to learn more')
return;
}
if (!performance.measureUserAgentSpecificMemory) {
console.log('performance.measureUserAgentSpecificMemory() is not available in this browser');
return;
}
const interval = measurementInterval();
console.log(`Running next memory measurement in ${Math.round(interval / 1000)} seconds`);
setTimeout(performMeasurement, interval);
}
measurementInterval() फ़ंक्शन, मिलीसेकंड में एक रैंडम इंटरवल का हिसाब लगाता है, ताकि औसतन हर पांच मिनट में एक मेज़रमेंट हो. अगर आपको इस फ़ंक्शन के पीछे की गणित के बारे में जानना है, तो एक्सपोनेंशियल डिस्ट्रिब्यूशन देखें.
function measurementInterval() {
const MEAN_INTERVAL_IN_MS = 5 * 60 * 1000;
return -Math.log(Math.random()) * MEAN_INTERVAL_IN_MS;
}
आखिर में, एसिंक performMeasurement() फ़ंक्शन, एपीआई को शुरू करता है, नतीजे को रिकॉर्ड करता है, और अगले मेज़रमेंट को शेड्यूल करता है.
async function performMeasurement() {
// 1. Invoke performance.measureUserAgentSpecificMemory().
let result;
try {
result = await performance.measureUserAgentSpecificMemory();
} catch (error) {
if (error instanceof DOMException && error.name === 'SecurityError') {
console.log('The context is not secure.');
return;
}
// Rethrow other errors.
throw error;
}
// 2. Record the result.
console.log('Memory usage:', result);
// 3. Schedule the next measurement.
scheduleMeasurement();
}
आखिर में, मेज़रमेंट शुरू करें.
// Start measurements.
scheduleMeasurement();
नतीजा कुछ इस तरह दिख सकता है:
// Console output:
{
bytes: 60_100_000,
breakdown: [
{
bytes: 40_000_000,
attribution: [{
url: 'https://example.com/',
scope: 'Window',
}],
types: ['JavaScript']
},
{
bytes: 20_000_000,
attribution: [{
url: 'https://example.com/iframe',
container: {
id: 'iframe-id-attribute',
src: '/iframe',
},
scope: 'Window',
}],
types: ['JavaScript']
},
{
bytes: 100_000,
attribution: [],
types: ['DOM']
},
],
}
मेमोरी के इस्तेमाल का कुल अनुमान, bytes फ़ील्ड में दिखाया जाता है. यह वैल्यू, लागू करने के तरीके पर काफ़ी हद तक निर्भर करती है. साथ ही, इसकी तुलना अलग-अलग ब्राउज़र में नहीं की जा सकती. यह एक ही ब्राउज़र के अलग-अलग वर्शन के हिसाब से भी बदल सकता है. इस वैल्यू में, मौजूदा प्रोसेस में मौजूद सभी iframe, उनसे जुड़ी विंडो, और वेब वर्कर की JavaScript और डीओएम मेमोरी शामिल होती है.
breakdown सूची में, इस्तेमाल की गई मेमोरी के बारे में ज़्यादा जानकारी दी गई है. हर एंट्री में मेमोरी के कुछ हिस्से के बारे में बताया जाता है. साथ ही, इसे यूआरएल से पहचाने गए विंडो, iframe, और वर्कर के सेट से जोड़ा जाता है. types फ़ील्ड में, मेमोरी से जुड़े मेमोरी टाइप की सूची दी गई है. ये मेमोरी टाइप, लागू करने के तरीके के हिसाब से तय होते हैं.
यह ज़रूरी है कि सभी सूचियों को सामान्य तरीके से इस्तेमाल किया जाए. साथ ही, किसी ब्राउज़र के आधार पर अनुमानों को हार्डकोड न किया जाए. उदाहरण के लिए, कुछ ब्राउज़र खाली breakdown या खाली attribution दिखा सकते हैं. अन्य ब्राउज़र, attribution में एक से ज़्यादा एंट्री दिखा सकते हैं. इससे पता चलता है कि वे यह नहीं पहचान सके कि इनमें से कौनसी एंट्री मेमोरी की मालिक है.
सुझाव/राय दें या शिकायत करें
वेब परफ़ॉर्मेंस कम्यूनिटी ग्रुप और Chrome टीम को performance.measureUserAgentSpecificMemory() के बारे में आपके विचारों और अनुभवों को जानकर बेहद खुशी होगी.
हमें एपीआई के डिज़ाइन के बारे में बताएं
क्या एपीआई के बारे में कुछ ऐसा है जो आपकी उम्मीद के मुताबिक काम नहीं करता? या क्या कोई ऐसी प्रॉपर्टी मौजूद नहीं है जिसे आपको अपने आइडिया को लागू करने के लिए इस्तेमाल करना है? performance.measureUserAgentSpecificMemory() GitHub रिपॉज़िटरी पर, स्पेसिफ़िकेशन से जुड़ी समस्या की शिकायत करें या किसी मौजूदा समस्या के बारे में अपने विचार जोड़ें.
लागू करने से जुड़ी समस्या की शिकायत करना
क्या आपको Chrome के साथ काम करने में कोई गड़बड़ी मिली? या क्या स्पेसिफ़िकेशन के हिसाब से लागू नहीं किया गया है? new.crbug.com पर जाकर, गड़बड़ी की शिकायत करें. पक्का करें कि आपने गड़बड़ी के बारे में ज़्यादा से ज़्यादा जानकारी दी हो. साथ ही, गड़बड़ी को दोहराने के लिए आसान निर्देश दिए हों. इसके अलावा, कॉम्पोनेंट को Blink>PerformanceAPIs पर सेट किया हो.
सहायता दिखाएं
क्या आपको performance.measureUserAgentSpecificMemory() का इस्तेमाल करना है? आपकी सार्वजनिक राय से, Chrome टीम को सुविधाओं को प्राथमिकता देने में मदद मिलती है. साथ ही, इससे अन्य ब्राउज़र बनाने वाली कंपनियों को यह पता चलता है कि इन सुविधाओं को सपोर्ट करना कितना ज़रूरी है. @ChromiumDev को ट्वीट करें
और हमें बताएं कि इसका इस्तेमाल कहां और कैसे किया जा रहा है.
काम के लिंक
- विस्तार से जानकारी देने वाला वीडियो
- डेमो | डेमो सोर्स
- ट्रैकिंग बग
- ChromeStatus.com एंट्री
- Origin Trial API के बाद हुए बदलाव
- ऑरिजिन ट्रायल खत्म हो गया
Acknowledgements
एपीआई डिज़ाइन की समीक्षा करने के लिए, डोमेनिक डेनिकोला, योआव वेइस, और मथियास बायनेंस का बहुत-बहुत धन्यवाद. साथ ही, Chrome में कोड की समीक्षा करने के लिए, डोमिनिक इन्फ़ुहर, हैनेस पेयर, केंटारो हारा, और माइकल लिपाउज़ का बहुत-बहुत धन्यवाद. मैं Per Parker, Philipp Weis, Olga Belomestnykh, Matthew Bolohan, और Neil Mckay को भी धन्यवाद देता हूं. इन्होंने उपयोगकर्ताओं से मिले सुझाव/राय/शिकायतें शेयर कीं. इससे एपीआई को बेहतर बनाने में काफ़ी मदद मिली.