Chrome में Accelerated रेंडरिंग

लेयर मॉडल

Tom Wiltzius
Tom Wiltzius

शुरुआती जानकारी

ज़्यादातर वेब डेवलपर के लिए, किसी वेब पेज का बुनियादी मॉडल डीओएम है. रेंडर करना, अक्सर किसी पेज के इस तरह के विज़ुअल को स्क्रीन पर तस्वीर में बदलने की प्रोसेस होती है. इसे समझना मुश्किल होता है. ग्राफ़िक कार्ड का फ़ायदा उठाने के लिए, आधुनिक ब्राउज़र ने हाल ही के सालों में रेंडरिंग के काम करने का तरीका बदल दिया है: आम तौर पर, इसे “हार्डवेयर से तेज़ी लाएं” कहा जाता है. किसी सामान्य वेब पेज (जैसे कि Canvas2D या WebGL नहीं) के बारे में बात करते समय, उस शब्द का असल में क्या मतलब है? इस लेख में उस बेसिक मॉडल के बारे में बताया गया है जो Chrome में, हार्डवेयर की मदद से वेब कॉन्टेंट को तेज़ी से रेंडर करने की सुविधा को मज़बूत बनाता है.

बिग, फ़ैटी चेतावनियां

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

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

यह समझना ज़रूरी है कि कुछ समय से Chrome में दो अलग-अलग रेंडरिंग पाथ थे: हार्डवेयर-Accelerated पाथ और पुराना सॉफ़्टवेयर पाथ. इस अपडेट के बाद, सभी पेज Windows, ChromeOS, और Android के लिए Chrome पर, हार्डवेयर एक्सेलरेटेड पाथ में नीचे चले जाएंगे. Mac और Linux पर, सिर्फ़ ऐसे पेज जिन्हें अपने कुछ कॉन्टेंट के लिए कंपोज़िट की ज़रूरत होती है, वे एक्सेलरेटेड पाथ में चले जाते हैं. इसके बारे में ज़्यादा जानने के लिए नीचे देखें कि किन पेजों के लिए कंपोज़िटिंग की ज़रूरत है. हालांकि, जल्द ही सभी पेज भी एक्सेलरेटेड पाथ में चले जाएंगे.

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

डीओएम से स्क्रीन तक

लेयर पेश करते हैं

जब कोई पेज लोड और पार्स हो जाता है, तो उसे ब्राउज़र में एक ऐसी संरचना के तौर पर दिखाया जाता है जिसे कई वेब डेवलपर जानते हैं: DOM. हालांकि, किसी पेज को रेंडर करते समय, ब्राउज़र में बीच के लेवल पर कई चीज़ें दिखती हैं. ये चीज़ें, डेवलपर को सीधे तौर पर नहीं दिखती हैं. इन संरचनाओं में से सबसे अहम है लेयर.

Chrome में कई अलग-अलग तरह की लेयर होती हैं: Renderlayers, DOM के सब-ट्री के लिए ज़िम्मेदार होती है और Graphicslayers, Renderlayers के सब-ट्री के लिए. हमारे लिए यहां बाद वाला विकल्प सबसे दिलचस्प है, क्योंकि Graphicslayer, जीपीयू में टेक्सचर के तौर पर अपलोड की जाती है. यहां से मैं Graphicslayer के तौर पर “लेयर” कहना चाहती हूं.

जीपीयू से जुड़ी शब्दावली को ध्यान में रखें: टेक्सचर क्या होता है? इसे बिटमैप इमेज की तरह समझें, जो मुख्य मेमोरी (यानी रैम) से वीडियो मेमोरी (यानी आपके जीपीयू पर वीआरएम) में चली जाती है. जीपीयू पर पहुंचने के बाद, इसे मेश ज्यामिति के साथ मैप किया जा सकता है. वीडियो गेम या सीएडी प्रोग्राम में, इस तकनीक का इस्तेमाल कंकाल 3D मॉडल को “स्किन” देने के लिए किया जाता है. Chrome, जीपीयू पर वेब पेज के कॉन्टेंट के कई हिस्से पाने के लिए टेक्सचर का इस्तेमाल करता है. टेक्सचर को आसानी से एक रेक्टैंगल रेक्टैंगल के साथ इस्तेमाल करके, अलग-अलग पोज़िशन और ट्रांसफ़ॉर्मेशन के हिसाब से मैप किया जा सकता है. 3D सीएसएस इसी तरह से काम करती है और तेज़ी से स्क्रोल करने के लिए भी यह बेहतरीन है. हालांकि, बाद में इन दोनों के बारे में ज़्यादा जानकारी दी जा सकती है.

लेयर कॉन्सेप्ट को समझने के लिए, कुछ उदाहरण देखते हैं.

Chrome में लेयर का अध्ययन करते समय, “रेंडरिंग” हेडिंग के नीचे, Dev टूल की सेटिंग में “कंपोज़िट लेयर बॉर्डर दिखाएं” फ़्लैग इस्तेमाल करने का एक बहुत अच्छा टूल है. यह बहुत ही आसानी से हाइलाइट करता है कि स्क्रीन पर लेयर कहां मौजूद हैं. इसे चालू करें. ये स्क्रीनशॉट और उदाहरण, यह फ़ॉर्म लिखे जाते समय नए Chrome कैनरी, Chrome 27 से लिए गए हैं.

इमेज 1: एक लेयर वाला पेज

<!doctype html>
<html>
<body>
  <div>I am a strange root.</div>
</body>
</html>
पेज की बेस लेयर के चारों ओर, कंपोज़िट लेयर रेंडर बॉर्डर का स्क्रीनशॉट
पेज के बेस लेयर के चारों तरफ़, कंपोज़िट की गई लेयर के बॉर्डर को रेंडर करने का स्क्रीनशॉट

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

इमेज 2: अपने लेयर में मौजूद कोई एलिमेंट

<!doctype html>
<html>
<body>
  <div style="transform: rotateY(30deg) rotateX(-30deg); width: 200px;">
    I am a strange root.
  </div>
</body>
</html>
घुमाई गई लेयर के रेंडर बॉर्डर का स्क्रीनशॉट
घुमाई गई लेयर के रेंडर बॉर्डर का स्क्रीनशॉट

<div> पर घूमने वाली 3D सीएसएस प्रॉपर्टी रखकर, हम देख सकते हैं कि किसी एलिमेंट का अपना लेयर मिलने पर यह कैसा दिखता है: नारंगी रंग के बॉर्डर पर ध्यान दें, जो इस व्यू में किसी लेयर को दिखाता है.

लेयर बनाने की शर्तें

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

  • 3D या पर्सपेक्टिव ट्रांसफ़ॉर्म सीएसएस प्रॉपर्टी
  • <video> एलिमेंट, फटाफट वीडियो डिकोड करने की सुविधा का इस्तेमाल कर रहा है
  • 3D (WebGL) या ऐक्सेलरेटेड 2D कॉन्टेक्स्ट वाले <canvas> एलिमेंट
  • मिश्रित प्लग इन (उदाहरण के लिए Flash)
  • सीएसएस ऐनिमेशन वाले एलिमेंट की ओपैसिटी की वजह से या ऐनिमेशन वाले ट्रांसफ़ॉर्म का इस्तेमाल करने की वजह से
  • Accelerated CSS फ़िल्टर वाले एलिमेंट
  • एलिमेंट में एक डिसेंडेंट है, जिसमें कंपोज़िटिंग लेयर है (दूसरे शब्दों में, अगर एलिमेंट में कोई चाइल्ड एलिमेंट है जो उसकी अपनी लेयर में है)
  • एलिमेंट का सिबलिंग है जिसका z-इंडेक्स कम है, जिसमें कंपोज़िटिंग लेयर है (दूसरे शब्दों में, इसे कंपोज़िट की गई लेयर के ऊपर रेंडर किया जाता है)

व्यवहारिक प्रभाव: ऐनिमेशन

हम लेयर को इधर-उधर ले जा सकते हैं. इससे वे ऐनिमेशन के लिए बहुत काम की बन जाती हैं.

इमेज 3: ऐनिमेटेड लेयर

<!doctype html>
<html>
<head>
  <style>
  div {
    animation-duration: 5s;
    animation-name: slide;
    animation-iteration-count: infinite;
    animation-direction: alternate;
    width: 200px;
    height: 200px;
    margin: 100px;
    background-color: gray;
  }
  @keyframes slide {
    from {
      transform: rotate(0deg);
    }
    to {
      transform: rotate(120deg);
    }
  }
  </style>
</head>
<body>
  <div>I am a strange root.</div>
</body>
</html>

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

उदाहरण के लिए, डेवलपर टूल की टाइमलाइन का यह व्यू देखें: लेयर के इधर-उधर घूमने के दौरान पेंट करने की कोई कार्रवाई नहीं होती.

ऐनिमेशन के दौरान, Dev टूल की टाइमलाइन का स्क्रीनशॉट
ऐनिमेशन के दौरान, Dev टूल की टाइमलाइन का स्क्रीनशॉट

अमान्य! दोबारा पेंट करना

अगर लेयर का कॉन्टेंट बदल जाता है, तो उसे फिर से पेंट करना होगा.

इमेज 4: लेयर को फिर से पेंट करना

<!doctype html>
<html>
<head>
  <style>
  div {
    animation-duration: 5s;
    animation-name: slide;
    animation-iteration-count: infinite;
    animation-direction: alternate;
    width: 200px;
    height: 200px;
    margin: 100px;
    background-color: gray;
  }
  @keyframes slide {
    from {
      transform: rotate(0deg);
    }
    to {
      transform: rotate(120deg);
    }
  }
  </style>
</head>
<body>
  <div id="foo">I am a strange root.</div>
  <input id="paint" type="button" value="repaint">
  <script>
    var w = 200;
    document.getElementById('paint').onclick = function() {
      document.getElementById('foo').style.width = (w++) + 'px';
    }
  </script>
</body>
</html>

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

क्या पेंट किया जा रहा है इसे देखने का एक अच्छा तरीका Dev टूल में “पेंट पेंट रेक्ट” टूल का इस्तेमाल करना है, जो Dev टूल की सेटिंग के “रेंडरिंग” हेडिंग के नीचे भी मौजूद है. इसे चालू करने के बाद, ध्यान दें कि बटन को क्लिक करने पर ऐनिमेट किया गया एलिमेंट और बटन, दोनों लाल हो जाते हैं.

पेंट रेक्टैंगल दिखाएं चेकबॉक्स का स्क्रीनशॉट
शो पेंट रेक्ट्स चेकबॉक्स का स्क्रीनशॉट

पेंट इवेंट, Dev टूल टाइमलाइन में भी दिखते हैं. तेज़ आंखों वाले पाठकों को लगता है कि वहां दो पेंट इवेंट होते हैं: एक लेयर के लिए और दूसरा बटन के लिए, जो अपनी डिप्रेस्ड स्थिति में/से बदलने पर फिर से पेंट हो जाता है.

लेयर को फिर से पेंट करने वाले Dev टूल की टाइमलाइन का स्क्रीनशॉट
किसी लेयर को फिर से पेंट करने के लिए, डेवलपर टूल की टाइमलाइन का स्क्रीनशॉट

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

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

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

इसे एक साथ रखना: स्क्रीन पर DOM

Chrome, डीओएम को स्क्रीन इमेज में कैसे बदलता है? सैद्धान्तिक तौर पर, यह:

  1. DOM को लेता है और उसे लेयर में बांटता है
  2. इनमें से हर लेयर को सॉफ़्टवेयर बिटमैप में अलग-अलग पेंट करता है
  3. उन्हें जीपीयू पर टेक्सचर के तौर पर अपलोड करता है
  4. अलग-अलग लेयर को एक साथ फ़ाइनल स्क्रीन इमेज में मिलाता है.

जब Chrome पहली बार किसी वेब पेज का फ़्रेम बनाता है, तब यह सब करना ज़रूरी है. लेकिन इसके बाद आगे के फ़्रेम के लिए कुछ शॉर्टकट लग सकते हैं:

  1. अगर कुछ सीएसएस प्रॉपर्टी बदल जाती हैं, तो किसी भी चीज़ को फिर से पेंट करने की ज़रूरत नहीं है. Chrome बस उन मौजूदा लेयर को फिर से कंपोज़ कर सकता है जो पहले से ही जीपीयू पर टेक्सचर के तौर पर मौजूद हैं.हालांकि, उन्हें अलग-अलग कंपोज़िटिंग प्रॉपर्टी के साथ इस्तेमाल किया जा सकता है. जैसे, अलग-अलग जगहों पर, अलग-अलग ओपैसिटी के साथ वगैरह.
  2. अगर लेयर का कोई हिस्सा अमान्य हो जाता है, तो उसे फिर से पेंट किया जाता है और फिर से अपलोड किया जाता है. अगर इसका कॉन्टेंट पहले जैसा ही रहता है, लेकिन इसके कंपोज़िट एट्रिब्यूट में बदलाव हो जाता है (जैसे कि इसका अनुवाद किया जाता है या इसकी ओपैसिटी में बदलाव होता है), तो Chrome इसे जीपीयू पर छोड़ सकता है और नया फ़्रेम बनाने के लिए फिर से कंपोज़िट कर सकता है.

जैसा कि अब आपको साफ़ तौर पर पता चल गया है, परफ़ॉर्मेंस को रेंडर करने पर लेयर-आधारित कंपोज़िटिंग मॉडल के गहरे असर होते हैं. जब किसी चीज़ को पेंट करने की ज़रूरत नहीं होती, तब कंपोज़िटिंग की तुलना में कम कीमत होती है. इसलिए, रेंडरिंग के दौरान डीबग करते समय, लेयर को फिर से पेंट करने से बचना बेहतर होता है. जानकार डेवलपर ऊपर दिए गए कंपोज़िटिंग ट्रिगर की सूची पर नज़र डालते हैं. उन्हें लगता है कि लेयर बनाने के लिए, ज़बरदस्ती ट्रिगर किए जा सकते हैं. ध्यान रखें कि ये चीज़ें बिना सोचे-समझे बनाई जा सकती हैं, क्योंकि ये खाली नहीं हैं: ये सिस्टम की रैम और जीपीयू (खास तौर पर मोबाइल डिवाइसों पर सीमित) में मेमोरी का इस्तेमाल करते हैं. इनमें से कई होने से, लॉजिक में अन्य ओवरहेड मिल सकते हैं, जो दिख रहे डेटा को ट्रैक करते हैं. असल में, कई लेयर रास्टराइज़ करने में लगने वाले समय को भी बढ़ा सकती हैं, अगर वे लेयर बड़ी हों और बहुत ज़्यादा जगहों पर ओवरलैप हो रही हों, जहां ऐसा पहले नहीं हुआ था. इससे, कभी-कभी इसे “ओवरड्रॉ” कहा जाता है. इसलिए, अपनी जानकारी का इस्तेमाल सोच-समझकर करें!

अभी के लिए बस इतना ही. लेयर मॉडल के व्यावहारिक नतीजों के बारे में कुछ और लेखों के लिए हमारे साथ बने रहें.

जानकारी पाने के दूसरे तरीके