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 टेस्टिंग, ताकि मेमोरी के असर का आकलन किया जा सके और मेमोरी में होने वाली गड़बड़ियों का पता लगाया जा सके.
  • मेमोरी के इस्तेमाल को सेशन की अवधि से जोड़कर, मेमोरी लीक होने की मौजूदगी या गैर-मौजूदगी की पुष्टि की जा सकती है.
  • मेमोरी के इस्तेमाल से पड़ने वाले असर को समझने के लिए, मेमोरी के इस्तेमाल को उपयोगकर्ता मेट्रिक से जोड़ना.

वेबसाइट का अलग-अलग ब्राउज़र पर चलना

ब्राउज़र सहायता

  • 89
  • 89
  • x
  • x

सोर्स

फ़िलहाल, यह एपीआई सिर्फ़ 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 सेकंड पर सेट होती है. हालांकि, यह समयसीमा पहले भी हो सकती है. Chrome को --enable-blink-features='ForceEagerMeasureMemory' कमांड-लाइन फ़्लैग के साथ शुरू करने पर, टाइम आउट कम हो जाता है. साथ ही, यह स्थानीय तौर पर डीबग करने और टेस्ट करने में मदद करता है.

उदाहरण

हम एपीआई के इस्तेमाल का सुझाव देते हैं कि आप एक ग्लोबल मेमोरी मॉनिटर बनाएं. यह पूरे वेब पेज के मेमोरी के इस्तेमाल का सैंपल देता है और नतीजों को एग्रीगेशन और विश्लेषण के लिए सर्वर पर भेजता है. समय-समय पर, उदाहरण के लिए हर 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 और DOM मेमोरी शामिल होती है.

breakdown सूची में, इस्तेमाल की गई मेमोरी के बारे में ज़्यादा जानकारी मिलती है. हर एंट्री मेमोरी के कुछ हिस्से की जानकारी देती है और उसे यूआरएल से पहचानी जाने वाली विंडो, iframe, और वर्कर के सेट को एट्रिब्यूट करती है. types फ़ील्ड में, मेमोरी से जुड़ी खास तरह की मेमोरी के टाइप की सूची होती है.

यह ज़रूरी है कि सभी सूचियों को एक सामान्य तरीके से समझा जाए और किसी खास ब्राउज़र के आधार पर हार्डकोड न लगाया जाए. उदाहरण के लिए, कुछ ब्राउज़र खाली breakdown या खाली attribution दिखा सकते हैं. अन्य ब्राउज़र attribution में एक से ज़्यादा एंट्री दिखा सकते हैं, जिससे पता चलता है कि वे यह पता नहीं लगा सके कि इनमें से किन एंट्री के पास मेमोरी है.

सुझाव/राय दें या शिकायत करें

वेब परफ़ॉर्मेंस कम्यूनिटी ग्रुप और Chrome टीम, performance.measureUserAgentSpecificMemory() के बारे में आपके विचार और अनुभव जानना चाहेगी.

हमें एपीआई के डिज़ाइन के बारे में बताएं

क्या एपीआई के बारे में कुछ ऐसा है जो उम्मीद के मुताबिक काम नहीं करता? या क्या ऐसी प्रॉपर्टी मौजूद नहीं हैं जिस पर आपको अपने आइडिया को लागू करने की ज़रूरत है? performance.measureUserAgentspecificMemory() GitHub रेपो से जुड़ी, कोई खास समस्या दर्ज करें या किसी मौजूदा समस्या के बारे में अपनी राय दें.

लागू करने से जुड़ी समस्या की शिकायत करना

क्या आपको Chrome को लागू करने में कोई गड़बड़ी मिली? या क्या इसे लागू करने का तरीका, खास निर्देशों से अलग है? new.crbug.com पर बग की शिकायत करें. ज़्यादा से ज़्यादा जानकारी शामिल करना, गड़बड़ी का फिर से सामना करने के आसान निर्देश देना, और कॉम्पोनेंट को Blink>PerformanceAPIs पर सेट करना न भूलें. Glitch, जल्दी और आसान रेप्रस शेयर करने के लिए शानदार काम करता है.

सपोर्ट करें

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

मददगार लिंक

स्वीकार की गई

एपीआई डिज़ाइन की समीक्षाओं के लिए, डोमेनिक डेनिकोला, योव वाइस, मथायस बायनेंस, और Chrome में कोड की समीक्षा करने के लिए डॉमिनिक इन्फ़ुअर, हैनेस पेमेंटर, केंटारो हारा, माइकल लिपाउट्ज़ का बहुत-बहुत धन्यवाद. मैं पेर पार्कर, फ़िलिप वाइस, ओल्गा बेलोमेस्निख, मैथ्यू बोलोहान, और नील मैके को भी धन्यवाद देता हूं कि उन्होंने इस एपीआई को बेहतर बनाने के लिए, उपयोगकर्ताओं के बारे में ज़रूरी सुझाव दिए.

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