measureUserAgentspecificMemory() की मदद से, अपने वेब पेज के कुल मेमोरी इस्तेमाल पर नज़र रखें

प्रोडक्शन में अपने वेब पेज के मेमोरी इस्तेमाल को मेज़र करने का तरीका जानें, ताकि परफ़ॉर्मेंस में गिरावट का पता लगाया जा सके.

Brendan Kenny
Brendan Kenny
Ulan Degenbaev
Ulan Degenbaev

ब्राउज़र, वेब पेजों की मेमोरी को अपने-आप मैनेज करते हैं. जब भी कोई वेब पेज कोई ऑब्जेक्ट बनाता है, तो ब्राउज़र ऑब्जेक्ट को सेव करने के लिए, "हुड के नीचे" मेमोरी का एक हिस्सा तय करता है. मेमोरी एक सीमित संसाधन है. इसलिए, ब्राउज़र यह पता लगाने के लिए गैर-ज़रूरी डेटा इकट्ठा करता है कि कब किसी ऑब्जेक्ट की ज़रूरत नहीं है. साथ ही, वह मेमोरी में मौजूद डेटा को खाली करता है.

हालांकि, यह तरीका हमेशा काम नहीं करता. साथ ही, यह साबित हो चुका है कि किसी भी वीडियो में मौजूद सभी ऑब्जेक्ट का पता लगाना असंभव है. इसलिए, ब्राउज़र "किसी ऑब्जेक्ट की ज़रूरत है" के बजाय "किसी ऑब्जेक्ट को ऐक्सेस किया जा सकता है" के हिसाब से काम करते हैं. अगर वेब पेज, अपने वैरिएबल और ऐक्सेस किए जा सकने वाले अन्य ऑब्जेक्ट के फ़ील्ड के ज़रिए किसी ऑब्जेक्ट तक नहीं पहुंच सकता, तो ब्राउज़र सुरक्षित तरीके से उस ऑब्जेक्ट को फिर से हासिल कर सकता है. इन दोनों के बीच के अंतर की वजह से, मेमोरी लीक होती है. इस बारे में नीचे दिए गए उदाहरण में बताया गया है.

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 एपीआई से किस तरह अलग है?

अगर आपको मौजूदा नॉन-स्टैंडर्ड performance.memory एपीआई के बारे में पता है, तो हो सकता है कि आप सोच रहे हों कि नया एपीआई इससे किस तरह अलग है. मुख्य अंतर यह है कि पुराना एपीआई, JavaScript ढेर का साइज़ दिखाता है, जबकि नया एपीआई, वेब पेज के इस्तेमाल की गई मेमोरी का अनुमान लगाता है. यह अंतर तब अहम हो जाता है, जब Chrome एक ही हेप को कई वेब पेजों (या एक ही वेब पेज के कई इंस्टेंस) के साथ शेयर करता है. ऐसे मामलों में, पुराने एपीआई का नतीजा मनमुताबिक हो सकता है. पुराने एपीआई को लागू करने के लिए, "हीप" जैसे खास शब्दों का इस्तेमाल किया जाता है. इसलिए, इसे स्टैंडर्ड बनाना मुमकिन नहीं है.

एक और अंतर यह है कि नया एपीआई, ग़ैर-ज़रूरी डेटा हटाने के दौरान मेमोरी मेज़रमेंट करता है. इससे नतीजों में मौजूद ग़ैर-ज़रूरी आवाज़ें कम हो जाती हैं. हालांकि, नतीजे मिलने में कुछ समय लग सकता है. ध्यान दें कि अन्य ब्राउज़र, गै़रबेज कलेक्शन के बिना नए एपीआई को लागू करने का फ़ैसला ले सकते हैं.

इस्तेमाल के सुझाए गए उदाहरण

किसी वेब पेज का मेमोरी इस्तेमाल, इवेंट, उपयोगकर्ता ऐक्शन, और 'ट्रैश' इकट्ठा करने के समय पर निर्भर करता है. इसलिए, मेमोरी मेज़रमेंट एपीआई का मकसद, प्रोडक्शन से मेमोरी के इस्तेमाल का डेटा इकट्ठा करना है. अलग-अलग कॉल के नतीजे कम काम के होते हैं. इस्तेमाल के उदाहरण:

  • वेब पेज के नए वर्शन को रोल आउट करने के दौरान, नई मेमोरी लीक का पता लगाने के लिए, रिग्रेशन का पता लगाना.
  • नई सुविधा की A/B टेस्टिंग, ताकि मेमोरी के असर का आकलन किया जा सके और मेमोरी में होने वाली गड़बड़ियों का पता लगाया जा सके.
  • मेमोरी के इस्तेमाल को सेशन की अवधि से जोड़कर, मेमोरी लीक की मौजूदगी या अनुपस्थिति की पुष्टि करना.
  • मेमोरी के इस्तेमाल का कुल असर समझने के लिए, मेमोरी के इस्तेमाल को उपयोगकर्ता मेट्रिक के साथ जोड़ना.

ब्राउज़र के साथ काम करना

ब्राउज़र के इस्तेमाल से जुड़ी सहायता

  • Chrome: 89.
  • Edge: 89.
  • Firefox: यह सुविधा काम नहीं करती.
  • Safari: यह सुविधा काम नहीं करती.

सोर्स

फ़िलहाल, यह एपीआई सिर्फ़ 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 पर सेट करना न भूलें. Glitch, जल्दी और आसान रेप्रोस शेयर करने के लिए शानदार काम करता है.

क्रिएटर के लिए अपना सपोर्ट दिखाना

क्या आपको performance.measureUserAgentSpecificMemory() का इस्तेमाल करना है? सार्वजनिक तौर पर सहायता पाने की सुविधा से, Chrome की टीम को सुविधाओं को प्राथमिकता देने में मदद मिलती है. साथ ही, इससे ब्राउज़र के अन्य वेंडर को यह पता चलता है कि इन सुविधाओं को उपलब्ध कराना कितना ज़रूरी है. @ChromiumDev को ट्वीट करें और हमें बताएं कि इसका इस्तेमाल कहां और कैसे किया जा रहा है.

मदद के लिए लिंक

धन्यवाद

एपीआई डिज़ाइन की समीक्षा करने के लिए, Domenic Denicola, Yoav Weiss, और Mathias Bynens का बहुत-बहुत धन्यवाद. साथ ही, Chrome में कोड की समीक्षा करने के लिए, Dominik Inführ, Hannes Payer, Kentaro Hara, और Michael Lippautz का भी बहुत-बहुत धन्यवाद. हम उपयोगकर्ताओं के ज़रूरी सुझावों और राय देने के लिए, Per Parker, Philipp Weis, Olga Belomestnykh, Matthew Bolohan, और Neil Mckay का भी धन्यवाद करते हैं. इनकी मदद से, एपीआई को बेहतर बनाया जा सका.

Unस्प्लैश पर हैरिसन ब्रॉडबेंट की हीरो इमेज