बड़े, जटिल लेआउट और लेआउट थ्रेशिंग से बचें

पब्लिश किया गया: 20 मार्च, 2015, पिछली बार अपडेट किया गया: 07 मई, 2025

लेआउट में ब्राउज़र, एलिमेंट की ज्यामितीय जानकारी का पता लगाता है: पेज में उनका साइज़ और जगह. हर एलिमेंट में, साइज़ की साफ़ तौर पर या निहित तौर पर जानकारी होगी. यह जानकारी, इस्तेमाल की गई सीएसएस, एलिमेंट के कॉन्टेंट या पैरंट एलिमेंट के आधार पर होगी. इस प्रोसेस को Chrome (और Edge जैसे ब्राउज़र) और Safari में लेआउट कहा जाता है. Firefox में इसे रीफ़्लो कहा जाता है, लेकिन प्रोसेस एक जैसी ही होती है.

स्टाइल की गणना की तरह ही, लेआउट की लागत से जुड़ी तुरंत समस्याएं ये हैं:

  1. उन एलिमेंट की संख्या जिन्हें लेआउट की ज़रूरत होती है. यह पेज के DOM साइज़ का एक उप-उत्पाद है.
  2. लेआउट की जटिलता.

खास जानकारी

  • लेआउट का सीधा असर इंटरैक्शन लेटेंसी पर पड़ता है
  • आम तौर पर, लेआउट पूरे दस्तावेज़ के लिए होता है.
  • DOM एलिमेंट की संख्या से परफ़ॉर्मेंस पर असर पड़ेगा. इसलिए, जहां भी हो सके वहां लेआउट को ट्रिगर करने से बचें.
  • फ़ोर्स किए गए सिंक्रोनस लेआउट और लेआउट थ्रैशिंग से बचें. स्टाइल वैल्यू पढ़ें और फिर स्टाइल में बदलाव करें.

इंटरैक्शन में लगने वाले समय पर लेआउट का असर

जब कोई उपयोगकर्ता पेज से इंटरैक्ट करता है, तो इंटरैक्शन जितनी जल्दी हो सके उतनी जल्दी होने चाहिए. किसी इंटरैक्शन को पूरा होने में लगने वाला समय, इंटरैक्शन में लगने वाला समय कहलाता है. यह समय तब खत्म होता है, जब ब्राउज़र इंटरैक्शन के नतीजे दिखाने के लिए अगला फ़्रेम दिखाता है. यह पेज की परफ़ॉर्मेंस का एक पहलू है, जिसे इंटरैक्शन टू नेक्स्ट पेंट मेट्रिक मेज़र करती है.

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

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

जहां भी हो सके, लेआउट का इस्तेमाल न करें

स्टाइल बदलने पर, ब्राउज़र यह जांच करता है कि क्या किसी बदलाव के लिए लेआउट का हिसाब लगाना ज़रूरी है और उस रेंडर ट्री को अपडेट करना है या नहीं. width, height, left या top जैसी "ज्यामितीय प्रॉपर्टी" में बदलाव करने के लिए, लेआउट की ज़रूरत होती है.

.box {
  width: 20px;
  height: 20px;
}

/**
  * Changing width and height
  * triggers layout.
  */

.box--expanded {
  width: 200px;
  height: 350px;
}

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

अगर लेआउट से बचना मुमकिन नहीं है, तो Chrome DevTools का फिर से इस्तेमाल करके देखें कि पेज लोड होने में कितना समय लग रहा है. साथ ही, यह भी पता लगाएं कि पेज लोड होने में लगने वाला समय, लेआउट की वजह से तो नहीं है. सबसे पहले, DevTools खोलें और टाइमलाइन टैब पर जाएं. इसके बाद, 'रिकॉर्ड करें' पर क्लिक करें और अपनी साइट के साथ इंटरैक्ट करें. रिकॉर्डिंग बंद करने पर, आपको यह जानकारी दिखेगी कि आपकी साइट की परफ़ॉर्मेंस कैसी रही:

DevTools में कई बैंगनी लेआउट ब्लॉक दिख रहे हैं.
Chrome DevTools में लेआउट में ज़्यादा समय दिख रहा है.

पिछले उदाहरण में दिए गए ट्रेस की जांच करने पर, हमें पता चलता है कि हर फ़्रेम के लिए लेआउट में 28 मिलीसेकंड से ज़्यादा समय लगता है. यह समय बहुत ज़्यादा है, क्योंकि ऐनिमेशन में किसी फ़्रेम को स्क्रीन पर दिखाने के लिए 16 मिलीसेकंड का समय होता है. इस इमेज में यह भी देखा जा सकता है कि DevTools,आपको ट्री का साइज़ (इस मामले में 1,618 एलिमेंट) और कितने नोड को लेआउट की ज़रूरत थी (इस मामले में पांच) बताएगा.

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

एक साथ सिंक होने वाले लेआउट से बचना

फ़्रेम को स्क्रीन पर शिप करने का क्रम यह है:

लेआउट के तौर पर फ़्लेक्सबॉक्स का इस्तेमाल करना.
रेंडर करने का तरीका

सबसे पहले JavaScript चलता है, फिर स्टाइल का हिसाब लगाया जाता है, फिर लेआउट. हालांकि, JavaScript की मदद से ब्राउज़र को पहले से लेआउट दिखाने के लिए मजबूर किया जा सकता है. इसे फ़ोर्स्ड सिंक्रोनस लेआउट या कभी-कभी फ़ोर्स्ड रीफ़्लो कहा जाता है.

सबसे पहले यह ध्यान रखें कि JavaScript के चलने पर, पिछले फ़्रेम की सभी पुरानी लेआउट वैल्यू आपके लिए क्वेरी करने के लिए उपलब्ध होती हैं. उदाहरण के लिए, अगर आपको फ़्रेम की शुरुआत में किसी एलिमेंट (उसे "बॉक्स" कहें) की ऊंचाई लिखनी है, तो कुछ ऐसा कोड लिखें:

// Schedule our function to run at the start of the frame:
requestAnimationFrame(logBoxHeight);

function logBoxHeight () {
  // Gets the height of the box in pixels and logs it out:
  console.log(box.offsetHeight);
}

अगर आपने बॉक्स की ऊंचाई पूछने से पहले, उसके स्टाइल में बदलाव कर दिया है, तो समस्याएं आ सकती हैं:

function logBoxHeight () {
  box.classList.add('super-big');

  // Gets the height of the box in pixels and logs it out:
  console.log(box.offsetHeight);
}

अब, ऊंचाई के सवाल का जवाब देने के लिए, ब्राउज़र को super-big क्लास जोड़ने की वजह से, पहले स्टाइल में बदलाव लागू करना होगा और फिर लेआउट चलाना होगा. ऐसा करने पर ही, यह सही ऊंचाई दिखा पाएगा. यह काम ज़रूरी नहीं है और इसमें ज़्यादा पैसे भी खर्च हो सकते हैं.

इस वजह से, आपको स्टाइल को हमेशा एक साथ पढ़ना चाहिए और पहले उन्हें पढ़ना चाहिए (जहां ब्राउज़र पिछले फ़्रेम की लेआउट वैल्यू का इस्तेमाल कर सकता है). इसके बाद, कोई भी बदलाव करें:

पिछले फ़ंक्शन का ज़्यादा असरदार वर्शन यह होगा:

function logBoxHeight () {
  // Gets the height of the box in pixels and logs it out:
  console.log(box.offsetHeight);

  box.classList.add('super-big');
}

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

लेआउट थ्रैशिंग से बचना

फ़ोर्स किए गए सिंक्रोनस लेआउट को और भी खराब बनाने का एक तरीका है: एक के बाद एक कई लेआउट बनाएं. इस कोड को देखें:

function resizeAllParagraphsToMatchBlockWidth () {
  // Puts the browser into a read-write-read-write cycle.
  for (let i = 0; i < paragraphs.length; i++) {
    paragraphs[i].style.width = `${box.offsetWidth}px`;
  }
}

यह कोड, पैराग्राफ़ के ग्रुप पर लूप करता है और हर पैराग्राफ़ की चौड़ाई को "बॉक्स" नाम के एलिमेंट की चौड़ाई से मैच करने के लिए सेट करता है. यह समस्या ज़्यादा नुकसानदेह नहीं लगती, लेकिन समस्या यह है कि लूप के हर दोहराव में, स्टाइल की वैल्यू (box.offsetWidth) को पढ़ा जाता है और फिर पैराग्राफ़ (paragraphs[i].style.width) की चौड़ाई को अपडेट करने के लिए, तुरंत उसका इस्तेमाल किया जाता है. लूप के अगले दोहराव में, ब्राउज़र को इस बात का ध्यान रखना होगा कि offsetWidth का पिछली बार अनुरोध किए जाने (पिछले दोहराव में) के बाद, स्टाइल बदल गई हैं. इसलिए, उसे स्टाइल में हुए बदलावों को लागू करना होगा और लेआउट चलाना होगा. ऐसा हर बार होगा.

इस सैंपल को ठीक करने के लिए, वैल्यू को फिर से रीड करें और फिर लिखें:

// Read.
const width = box.offsetWidth;

function resizeAllParagraphsToMatchBlockWidth () {
  for (let i = 0; i < paragraphs.length; i++) {
    // Now write.
    paragraphs[i].style.width = `${width}px`;
  }
}

फ़ोर्स किए गए सिंक्रोनस लेआउट और थ्रैशिंग की पहचान करना

DevTools में फ़ोर्स्ड रीफ़्लो की अहम जानकारी होती है. इससे, फ़ोर्स्ड सिंक्रोनस लेआउट (जिसे "फ़ोर्स्ड रीफ़्लो" भी कहा जाता है) के मामलों की तुरंत पहचान करने में मदद मिलती है:

DevTools में, &#39;w&#39; नाम के फ़ंक्शन की पहचान करके, फ़ोर्स्ड रीफ़्लो की अहम जानकारी दिखाने वाला इलस्ट्रेशन. इस फ़ंक्शन की वजह से फ़ोर्स्ड रीफ़्लो हो रहा है.
Chrome DevTools में, फ़ोर्स्ड रीफ़्लो की अहम जानकारी.

फ़ील्ड में फ़ोर्स किए गए सिंक्रोनस लेआउट की पहचान, forcedStyleAndLayoutDuration प्रॉपर्टी का इस्तेमाल करके Long Animation Frame API स्क्रिप्ट एट्रिब्यूशन का इस्तेमाल करके भी की जा सकती है.