बड़े DOM साइज़, इंटरैक्टिविटी पर कैसे असर डालते हैं और इस बारे में क्या किया जा सकता है

बड़े डीओएम साइज़ का इंटरैक्टिविटी पर असर आपकी उम्मीद से ज़्यादा होता है. इस गाइड में बताया गया है कि ऐसा क्यों किया जा सकता है और इस बारे में क्या किया जा सकता है.

इसमें कोई तरीका नहीं है: जब कोई वेब पेज बनाया जाता है, तो उस पेज में डॉक्यूमेंट ऑब्जेक्ट मॉडल (DOM) होगा. डीओएम आपके पेज के एचटीएमएल का स्ट्रक्चर दिखाता है. साथ ही, JavaScript और सीएसएस को पेज के स्ट्रक्चर और कॉन्टेंट का ऐक्सेस देता है.

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

इससे बहुत बड़े DOM वाले पेजों में उस समय समस्या होती है जब DOM को संशोधित या अपडेट करने वाले इंटरैक्शन महंगे लेआउट वर्क को ट्रिगर करते हैं, जिससे पेज की तेज़ी से प्रतिक्रिया देने की क्षमता प्रभावित होती है. लेआउट का महंगा काम, किसी पेज के इंटरैक्शन टू नेक्स्ट पेंट (आईएनपी) पर असर डाल सकता है; अगर आपको किसी पेज से, उपयोगकर्ता के इंटरैक्शन का तुरंत जवाब देना है, तो यह पक्का करना ज़रूरी है कि आपके डीओएम साइज़ ज़रूरत के मुताबिक ही हों.

किसी पेज का डीओएम कब बहुत बड़ा होता है?

Lighthouse के मुताबिक, किसी पेज का डीओएम साइज़ 1,400 नोड से ज़्यादा होने पर बहुत ज़्यादा होता है. किसी पेज के डीओएम की संख्या 800 नोड से ज़्यादा होने पर, लाइटहाउस चेतावनियां दिखाना शुरू कर देगा. यहां दिए गए एचटीएमएल का उदाहरण देखें:

<ul>
  <li>List item one.</li>
  <li>List item two.</li>
  <li>List item three.</li>
</ul>

ऊपर दिए गए कोड में, चार डीओएम एलिमेंट हैं: <ul> एलिमेंट और उसके तीन <li> चाइल्ड एलिमेंट. आपके वेब पेज में इससे ज़्यादा नोड होंगे, इसलिए यह समझना ज़रूरी है कि डीओएम साइज़ को जांच में रखने के लिए क्या किया जा सकता है—साथ ही, किसी पेज के डीओएम को जितना हो सके उतना छोटा करने के बाद रेंडरिंग काम को ऑप्टिमाइज़ करने की अन्य रणनीतियां.

बड़े डीओएम, पेज की परफ़ॉर्मेंस पर कैसे असर डालते हैं?

बड़े डीओएम, पेज की परफ़ॉर्मेंस पर कुछ तरीकों से असर डालते हैं:

  1. पेज को पहली बार रेंडर करने के दौरान. जब किसी पेज पर सीएसएस लागू की जाती है, तो डीओएम से मिलता-जुलता एक स्ट्रक्चर बन जाता है. इस स्ट्रक्चर को सीएसएस ऑब्जेक्ट मॉडल (CSSOM) के नाम से जाना जाता है. जैसे-जैसे सीएसएस सिलेक्टर की विशेषता बढ़ती जाती है, CSSOM ज़्यादा जटिल हो जाता है. साथ ही, वेब पेज को स्क्रीन पर ड्रॉ करने के लिए ज़रूरी लेआउट, स्टाइल, कंपोज़िटिंग, और पेंट करने के काम को चलाने में ज़्यादा समय लगता है. अतिरिक्त काम की वजह से, पेज लोड होने की शुरुआत में होने वाले इंटरैक्शन के लिए, इंटरैक्शन में लगने वाला समय बढ़ जाता है.
  2. जब इंटरैक्शन, एलिमेंट इंसर्शन या मिटाकर या DOM कॉन्टेंट और स्टाइल में बदलाव करके DOM में बदलाव करते हैं, तो उस अपडेट को रेंडर करने के लिए ज़रूरी काम की वजह से लेआउट, स्टाइल, कंपोज़िटिंग, और पेंट का काम बहुत महंगा पड़ सकता है. जैसा कि पेज के शुरुआती रेंडर के मामले में होता है, सीएसएस सिलेक्टर की विशेषता में बढ़ोतरी, रेंडरिंग के काम में तब बढ़ सकती है, जब इंटरैक्शन के बाद एचटीएमएल एलिमेंट को डीओएम में डाला जाता है.
  3. जब JavaScript, डीओएम पर क्वेरी करता है, तो डीओएम एलिमेंट के रेफ़रंस, मेमोरी में सेव हो जाते हैं. उदाहरण के लिए, अगर किसी पेज पर सभी <div> एलिमेंट चुनने के लिए document.querySelectorAll को कॉल किया जाता है, तो बड़ी संख्या में डीओएम एलिमेंट दिखने पर मेमोरी की लागत बेहतर हो सकती है.
Chrome DevTools के परफ़ॉर्मेंस पैनल में, बहुत ज़्यादा रेंडरिंग काम की वजह से लंबे टास्क का स्क्रीनशॉट. लंबे टास्क के कॉल स्टैक में, पेज के स्टाइल को फिर से कैलकुलेट करने में काफ़ी समय लग रहा है. साथ ही, प्री-पेंट भी दिखता है.
Chrome DevTools के परफ़ॉर्मेंस प्रोफ़ाइलर में दिखाया गया एक लंबा टास्क. दिखाया गया लंबा टास्क, JavaScript के ज़रिए बड़े DOM में डीओएम एलिमेंट डालने से होता है.

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

मैं डीओएम का साइज़ कैसे मेज़र करूं?

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

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

document.querySelectorAll('*').length;

अगर आपको डीओएम के साइज़ को रीयल टाइम में देखना है, तो परफ़ॉर्मेंस मॉनिटर करने वाले टूल का इस्तेमाल भी किया जा सकता है. इस टूल का इस्तेमाल करके, मौजूदा डीओएम साइज़ के साथ-साथ, लेआउट और स्टाइलिंग ऑपरेशन (और परफ़ॉर्मेंस के दूसरे पहलुओं) को भी जोड़ा जा सकता है.

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

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

मैं किसी इंटरैक्शन से प्रभावित DOM एलिमेंट की संख्या कैसे माप सकता/सकती हूं?

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

Chrome DevTools के परफ़ॉर्मेंस पैनल में, चुनी गई स्टाइल को दोबारा कैलकुलेट करने की गतिविधि का स्क्रीनशॉट. सबसे ऊपर, इंटरैक्शन ट्रैक एक क्लिक इंटरैक्शन दिखाता है. ज़्यादातर काम, स्टाइल को दोबारा कैलकुलेट करने और प्री-पेंट करने में खर्च होता है. सबसे नीचे एक पैनल, चुनी गई गतिविधि के बारे में ज़्यादा जानकारी दिखाता है. इस जानकारी से पता चलता है कि 2,547 डीओएम एलिमेंट पर असर पड़ा है.
स्टाइल को दोबारा कैलकुलेट करने के बाद, डीओएम में उन एलिमेंट की संख्या देखना जिन पर असर पड़ा है. ध्यान दें कि इंटरैक्शन ट्रैक में, इंटरैक्शन का शेड किया गया हिस्सा 200 मिलीसेकंड से ज़्यादा की इंटरैक्शन अवधि का हिस्सा दिखाता है, जिसे "अच्छा" के तौर पर मार्क किया गया है) आईएनपी के लिए थ्रेशोल्ड.

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

मैं डीओएम का साइज़ कैसे कम करूं?

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

<div>
  <div>
    <div>
      <div>
        <!-- Contents -->
      </div>
    </div>
  </div>
</div>

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

डीओएम डेप्थ, आपके इस्तेमाल किए जाने वाले फ़्रेमवर्क का लक्षण भी हो सकती है. खास तौर पर, कॉम्पोनेंट पर आधारित फ़्रेमवर्क के लिए, आपको पैरंट कंटेनर में कई कॉम्पोनेंट को नेस्ट करना होगा. उदाहरण के लिए, JSX इस्तेमाल करने वाले फ़्रेमवर्क.

हालांकि, कई फ़्रेमवर्क आपको फ़्रैगमेंट का इस्तेमाल करके कॉम्पोनेंट को नेस्ट करने से बचने की सुविधा देते हैं. ऐसे कॉम्पोनेंट-आधारित फ़्रेमवर्क जिनमें सुविधा के तौर पर फ़्रैगमेंट मिलते हैं. इनमें इनके अलावा, और भी चीज़ें शामिल हो सकती हैं:

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

अन्य रणनीतियां

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

इसे अलग तरीके से लिखें

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

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

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

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

सीएसएस सिलेक्टर की मुश्किलों को सीमित करना

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

content-visibility प्रॉपर्टी का इस्तेमाल करना

सीएसएस, content-visibility प्रॉपर्टी की सुविधा देती है. यह ऑफ़-स्क्रीन डीओएम एलिमेंट को लेज़ी तरीके से रेंडर करने का बेहतरीन तरीका है. जैसे-जैसे एलिमेंट, व्यूपोर्ट के पास पहुंचते हैं, उन्हें मांग पर रेंडर किया जाता है. content-visibility के फ़ायदे न सिर्फ़ शुरुआती पेज रेंडर करने में काफ़ी काम आते हैं, बल्कि उपयोगकर्ता इंटरैक्शन की वजह से पेज DOM के बदलने पर भी ऑफ़स्क्रीन एलिमेंट के लिए रेंडरिंग के काम को छोड़ देते हैं.

नतीजा

अपनी वेबसाइट के आईएनपी को ऑप्टिमाइज़ करने का यह अच्छा तरीका है कि अपने डीओएम साइज़ को कम करके सिर्फ़ उसके लिए ज़रूरी बनाएं. ऐसा करके, DOM अपडेट होने पर ब्राउज़र को लेआउट और रेंडरिंग का काम करने में लगने वाला समय कम किया जा सकता है. भले ही, डीओएम साइज़ को सही तरीके से कम न किया जा सके, फिर भी कुछ ऐसी तकनीक हैं जिनकी मदद से डीओएम सबट्री में रेंडरिंग काम को अलग किया जा सकता है. जैसे, सीएसएस कंटेनमेंट और content-visibility सीएसएस प्रॉपर्टी.

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

लुइस रीड की किताब Unस्प्लैश से हीरो इमेज.