आइए, मुख्य डेटा स्ट्रक्चर पर नज़र डालते हैं, जो रेंडरिंग पाइपलाइन के इनपुट और आउटपुट होते हैं.
ये डेटा स्ट्रक्चर इस तरह हैं:
- फ़्रेम ट्री लोकल और रिमोट नोड से बने होते हैं. ये नोड दिखाते हैं कि कौनसे वेब दस्तावेज़, रेंडर करने की प्रोसेस में हैं और कौनसे ब्लिंक रेंडरर.
- इम्यूटेबल फ़्रैगमेंट ट्री, लेआउट कंस्ट्रेंट एल्गोरिदम का आउटपुट और इसमें इनपुट दिखाता है.
- प्रॉपर्टी ट्री में किसी वेब दस्तावेज़ के ट्रांसफ़ॉर्म, क्लिप, इफ़ेक्ट, और स्क्रोल की हैरारकी को दिखाया जाता है. इनका इस्तेमाल, पूरी पाइपलाइन में किया जाता है.
- डिसप्ले लिस्ट और पेंट के हिस्से, रास्टर और लेयराइज़ेशन एल्गोरिदम के इनपुट हैं.
- कंपोज़िटर फ़्रेम, जीपीयू का इस्तेमाल करके ड्रॉ करने के लिए इस्तेमाल होने वाली सरफ़ेस, रेंडर सरफ़ेस, और जीपीयू टेक्सचर टाइल को एनकैप्सुलेट करते हैं.
इन डेटा स्ट्रक्चर को समझने से पहले, नीचे दिया गया उदाहरण आर्किटेक्चर की समीक्षा के तहत लिया गया एक उदाहरण है. इस उदाहरण का इस्तेमाल इस दस्तावेज़ में किया गया है. साथ ही, यह भी बताया गया है कि डेटा स्ट्रक्चर इस पर कैसे लागू होता है.
<!-- Example code -->
<html>
<div style="overflow: hidden; width: 100px; height: 100px;">
<iframe style="filter: blur(3px);
transform: rotateZ(1deg);
width: 100px; height: 300px"
id="one" src="foo.com/etc"></iframe>
</div>
<iframe style="top:200px;
transform: scale(1.1) translateX(200px)"
id="two" src="bar.com"></iframe>
</html>
पेड़ों को फ़्रेम करना
Chrome कभी-कभी क्रॉस-ऑरिजिन फ़्रेम को अपने पैरंट फ़्रेम से, किसी दूसरी रेंडर प्रोसेस में रेंडर कर सकता है.
उदाहरण के कोड में, कुल तीन फ़्रेम हैं:
साइट आइसोलेशन के साथ, Chromium इस वेब पेज को रेंडर करने के लिए दो प्रोसेस का इस्तेमाल करता है. उस वेब पेज के लिए, रेंडर करने की हर प्रोसेस में फ़्रेम ट्री को अपने अलग तरीके से दिखाया जाता है:
किसी अलग प्रोसेस में रेंडर होने वाले फ़्रेम को रिमोट फ़्रेम के तौर पर दिखाया जाता है. रिमोट फ़्रेम में वह कम से कम जानकारी होती है जो रेंडरिंग के दौरान प्लेसहोल्डर के तौर पर काम करने के लिए ज़रूरी होती है. उदाहरण के लिए, इसका डाइमेंशन. रिमोट फ़्रेम में ऐसी कोई जानकारी मौजूद नहीं होती जो इसकी असल कॉन्टेंट को रेंडर करने के लिए ज़रूरी हो.
वहीं दूसरी ओर, लोकल फ़्रेम एक ऐसा फ़्रेम दिखाता है जो स्टैंडर्ड रेंडरिंग पाइपलाइन से गुज़रता है. लोकल फ़्रेम में वह पूरी जानकारी होती है जो उस फ़्रेम के डेटा (जैसे कि डीओएम ट्री और स्टाइल डेटा) को रेंडर करने और दिखाने के लिए ज़रूरी होती है.
रेंडरिंग पाइपलाइन, लोकल फ़्रेम ट्री के फ़्रैगमेंट की जानकारी पर काम करती है.
foo.com
को मुख्य फ़्रेम के तौर पर शामिल करके, एक ज़्यादा मुश्किल उदाहरण को ध्यान में रखें:
<iframe src="bar.com"></iframe>
साथ ही, यहां दिया गया bar.com
सबफ़्रेम:
<iframe src="foo.com/etc"></iframe>
हालांकि, अब भी सिर्फ़ दो रेंडरर हैं, लेकिन अब भी लोकल फ़्रेम ट्री के तीन फ़्रैगमेंट मौजूद हैं. इनमें से दो, foo.com
के लिए रेंडर करने की प्रोसेस में और दूसरा bar.com
के लिए रेंडर करने की प्रोसेस में है:
वेब पेज के लिए एक कंपोज़िटर फ़्रेम बनाने के लिए, Viiz साथ-साथ तीन लोकल फ़्रेम ट्री में से हर एक के रूट फ़्रेम से एक कंपोज़िटर फ़्रेम का अनुरोध करता है और फिर उन्हें एग्रीगेट करता है. कंपोज़िटर फ़्रेम सेक्शन पर भी गौर करें.
foo.com
का मुख्य फ़्रेम और foo.com/other-page
सबफ़्रेम, एक ही फ़्रेम ट्री का हिस्सा हैं और एक ही प्रोसेस में रेंडर किए गए हैं.
हालांकि, दोनों फ़्रेम अब भी अलग-अलग दस्तावेज़ की लाइफ़साइकल होते हैं, क्योंकि वे अलग-अलग लोकल फ़्रेम ट्री के फ़्रैगमेंट का हिस्सा हैं.
इस वजह से, एक अपडेट में दोनों के लिए एक कंपोज़िटर फ़्रेम जनरेट करना मुमकिन नहीं है.
रेंडर करने की प्रोसेस में foo.com/other-page
के लिए जनरेट किए गए कंपोज़िटर फ़्रेम को सीधे foo.com
मुख्य फ़्रेम के लिए कंपोज़िटर फ़्रेम में कंपोज़िटर फ़्रेम में कंपोज़ करने के लिए ज़रूरी जानकारी नहीं मिली है.
उदाहरण के लिए, प्रोसेस से बाहर का bar.com
पैरंट फ़्रेम, iframe को सीएसएस में बदलकर या iframe के कुछ हिस्सों को उसके DOM में अन्य एलिमेंट से छिपाकर, foo.com/other-url
iframe के डिसप्ले पर असर डाल सकता है.
विज़ुअल प्रॉपर्टी अपडेट करने वाला वॉटरफ़ॉल
डिवाइस स्केल फ़ैक्टर और व्यूपोर्ट साइज़ जैसी विज़ुअल प्रॉपर्टी, रेंडर किए गए आउटपुट पर असर डालती हैं. साथ ही, इन्हें लोकल फ़्रेम ट्री के फ़्रैगमेंट के बीच सिंक होना चाहिए. हर लोकल फ़्रेम ट्री फ़्रैगमेंट के रूट में एक विजेट ऑब्जेक्ट होता है. विज़ुअल प्रॉपर्टी में अपडेट, मुख्य फ़्रेम के विजेट पर जाते हैं. इसके बाद, बाकी विजेट ऊपर से नीचे तक दिखते हैं.
उदाहरण के लिए, जब व्यूपोर्ट का साइज़ बदलता है:
यह प्रोसेस तुरंत नहीं होती, इसलिए, डुप्लीकेट विज़ुअल प्रॉपर्टी में सिंक टोकन भी शामिल होता है. Viz कंपोज़िटर इस सिंक टोकन का इस्तेमाल, सभी लोकल फ़्रेम ट्री फ़्रैगमेंट के मौजूदा सिंक टोकन के साथ कंपोज़िटर फ़्रेम सबमिट करने का इंतज़ार करने के लिए करता है. इस प्रोसेस में, कंपोज़िटर फ़्रेम को अलग-अलग विज़ुअल प्रॉपर्टी के साथ मिक्स करने से बचा जाता है.
नहीं बदला जा सकने वाला फ़्रैगमेंट ट्री
नहीं बदला जा सकने वाला फ़्रैगमेंट ट्री, रेंडरिंग पाइपलाइन के लेआउट स्टेज का आउटपुट होता है. यह पेज पर मौजूद सभी एलिमेंट की पोज़िशन और साइज़ दिखाता है. (बदलाव लागू किए बिना).
हर फ़्रैगमेंट, डीओएम एलिमेंट का एक हिस्सा दिखाता है. आम तौर पर, हर एलिमेंट में सिर्फ़ एक फ़्रैगमेंट होता है. हालांकि, प्रिंट करते समय इसे अलग-अलग पेजों में बांटने या एक से ज़्यादा कॉलम वाले कॉन्टेक्स्ट में कॉलम में बांटने पर और भी फ़्रैगमेंट हो सकते हैं.
लेआउट के बाद, हर फ़्रैगमेंट में बदलाव नहीं किया जा सकता और उसे फिर से कभी नहीं बदला जाता. अहम बात, हम कुछ अन्य पाबंदियां भी लगाते हैं. हम ये काम नहीं करते हैं:
- ट्री में किसी भी "ऊपर" संदर्भ को अनुमति दें. (बच्चे अपने पैरंट के लिए पॉइंटर नहीं रख सकते.)
- पेड़ से नीचे का "बबल" डेटा (कोई बच्चा सिर्फ़ अपने बच्चों की जानकारी पढ़ता है, अपने माता-पिता की नहीं).
इन पाबंदियों की मदद से, हम बाद के लेआउट के लिए फ़्रैगमेंट का फिर से इस्तेमाल कर पाते हैं. इन पाबंदियों के बिना, हमें अक्सर पूरे पेड़ को फिर से जनरेट करना पड़ता. हालांकि, यह महंगा है.
ज़्यादातर लेआउट आम तौर पर, समय के साथ होने वाले अपडेट होते हैं. उदाहरण के लिए, जब उपयोगकर्ता किसी एलिमेंट पर क्लिक करता है, तो यूज़र इंटरफ़ेस (यूआई) के छोटे हिस्से को अपडेट करने वाला वेब ऐप्लिकेशन. आम तौर पर, लेआउट को स्क्रीन पर असल में हुए बदलावों के हिसाब से ही काम करना चाहिए. ऐसा करने के लिए, हम पिछले ट्री के ज़्यादा से ज़्यादा हिस्सों का फिर से इस्तेमाल कर सकते हैं. इसका मतलब है कि (आम तौर पर) हमें सिर्फ़ पेड़ के स्पाइन को फिर से बनाने की ज़रूरत होती है.
आने वाले समय में, नहीं बदले जा सकने वाले इस डिज़ाइन से हमें दिलचस्प काम करने में मदद मिलेगी. जैसे, ज़रूरत पड़ने पर, थ्रेड की सीमाओं के बीच में नहीं बदले जा सकने वाले फ़्रैगमेंट ट्री को पास करना (किसी दूसरे थ्रेड पर बाद के चरण पूरे करने के लिए), शानदार लेआउट ऐनिमेशन के लिए कई ट्री जनरेट करना या पैरलल अनुमान वाले लेआउट करना. इससे हमें मल्टी-थ्रेडिंग लेआउट की सुविधा भी मिलती है.
इनलाइन फ़्रैगमेंट आइटम
इनलाइन कॉन्टेंट (मुख्य तौर पर स्टाइल किया गया टेक्स्ट) में थोड़े अलग तरीके का इस्तेमाल किया जाता है. बॉक्स और पॉइंटर वाली ट्री स्ट्रक्चर के बजाय, हम इनलाइन कॉन्टेंट को ट्री की जानकारी वाली फ़्लैट सूची में दिखाते हैं. इसका मुख्य फ़ायदा यह है कि इनलाइन के लिए एक फ़्लैट लिस्ट को दिखाने की सुविधा तेज़ी से काम करती है. इससे इनलाइन डेटा स्ट्रक्चर की जांच करने या क्वेरी करने में मदद मिलती है. साथ ही, मेमोरी की क्षमता भी कम होती है. वेब रेंडरिंग की परफ़ॉर्मेंस के लिए यह बहुत ज़रूरी है. ऐसा इसलिए, क्योंकि टेक्स्ट को रेंडर करना बहुत जटिल है. अगर बहुत ऑप्टिमाइज़ नहीं किया जाता है, तो यह पाइपलाइन का सबसे धीमा हिस्सा हो सकता है.
फ़्लैट सूची को इनलाइन फ़ॉर्मैट के कॉन्टेक्स्ट के हिसाब से बनाया जाता है. ऐसा, इनलाइन लेआउट सबट्री को गहराई से खोजने के क्रम में किया जाता है. सूची की हर एंट्री (ऑब्जेक्ट, डिसेंडेंट की संख्या) का ट्यूपल होती है. उदाहरण के लिए, इस DOM पर विचार करें:
<div style="width: 0;">
<span style="color: blue; position: relative;">Hi</span> <b>there</b>.
</div>
width
प्रॉपर्टी को 0 पर सेट किया गया है, ताकि लाइन "नमस्ते" और "वहां" के बीच में आ जाए.
इस स्थिति के लिए इनलाइन फ़ॉर्मैटिंग कॉन्टेक्स्ट को ट्री के तौर पर दिखाए जाने पर, यह ऐसा दिखता है:
{
"Line box": {
"Box <span>": {
"Text": "Hi"
}
},
"Line box": {
"Box <b>": {
"Text": "There"
}
},
{
"Text": "."
}
}
फ़्लैट सूची इस तरह दिखेगी:
- (लाइन बॉक्स, 2)
- (बॉक्स <span>, 1)
- (टेक्स्ट "नमस्ते", 0)
- (लाइन बॉक्स, 3)
- (बॉक्स <b>, 1)
- (टेक्स्ट "there", 0)
- (टेक्स्ट ".", 0)
इस डेटा स्ट्रक्चर का इस्तेमाल कई लोग कर सकते हैं: सुलभता एपीआई और ज्यामिति एपीआई, जैसे कि getClientRects
और contenteditable
.
हर सुविधा की ज़रूरी शर्तें अलग-अलग होती हैं.
ये कॉम्पोनेंट सुविधा कर्सर के ज़रिए फ़्लैट डेटा स्ट्रक्चर को ऐक्सेस करते हैं.
कर्सर में एपीआई मौजूद हैं, जैसे कि MoveToNext
, MoveToNextLine
, CursorForChildren
.
यह कर्सर, टेक्स्ट कॉन्टेंट के लिए बहुत असरदार होता है. इसकी कई वजहें हैं:
- गहराई के पहले खोज क्रम में इटरेट करना बहुत तेज़ है. इसका इस्तेमाल अक्सर किया जाता है, क्योंकि यह कैरेट (कैरेट) को मूव करने जैसा ही होता है. यह एक फ़्लैट सूची है, इसलिए डेप्थ-फ़र्स्ट सर्च (गहराई से शुरू की गई खोज) से सिर्फ़ अरे ऑफ़सेट को बढ़ाया जाता है, जिससे तेज़ इटरेशन और मेमोरी लोकलिटी की सुविधा मिलती है.
- यह वाइड-फ़र्स्ट सर्च की सुविधा देता है, जो तब ज़रूरी होता है, जब उदाहरण के लिए, लाइन और इनलाइन बॉक्स के बैकग्राउंड को पेंट करना.
- डिसेंडेंट की संख्या जानने से अगले सिबलिंग तेज़ी से मूव करते हैं (बस उस संख्या से अरे ऑफ़सेट बढ़ाएं).
प्रॉपर्टी ट्री
डीओएम, एलिमेंट का एक ट्री (साथ में टेक्स्ट नोड) होता है. साथ ही, सीएसएस, एलिमेंट पर कई स्टाइल लागू कर सकती है.
यह चार तरीकों से दिखता है:
- लेआउट: लेआउट कंस्ट्रेंट एल्गोरिदम के इनपुट.
- पेंट: एलिमेंट को कैसे पेंट और रास्टर करें (लेकिन इसके डिसेंडेंट नहीं).
- विज़ुअल: डीओएम सबट्री पर लागू किए गए रास्टर/ड्रॉ इफ़ेक्ट, जैसे कि ट्रांसफ़ॉर्म, फ़िल्टर, और क्लिपिंग.
- स्क्रोल करना: ऐक्सिस की अलाइन और गोल कोने वाले कोने में मौजूद सबट्री को क्लिप करने और स्क्रोल करने की सुविधा.
प्रॉपर्टी ट्री ऐसे डेटा स्ट्रक्चर हैं जो बताते हैं कि विज़ुअल और स्क्रोलिंग इफ़ेक्ट, डीओएम एलिमेंट पर कैसे लागू होते हैं. इनसे ऐसे सवालों के जवाब देने में मदद मिलती है: स्क्रीन के हिसाब से, दिया गया डीओएम एलिमेंट कहां है, इसके लेआउट का साइज़ और पोज़िशन क्या है? साथ ही: विज़ुअल और स्क्रोलिंग इफ़ेक्ट लागू करने के लिए, जीपीयू ऐक्शन के किस क्रम का इस्तेमाल होना चाहिए?
वेब पर विज़ुअल और स्क्रोल करने वाले इफ़ेक्ट को इस्तेमाल करना बहुत ही मुश्किल है. इसलिए, प्रॉपर्टी ट्री के लिए सबसे ज़रूरी है कि जटिलताओं को एक ही डेटा स्ट्रक्चर में बदल दिया जाए, जो उनकी स्ट्रक्चर और मतलब को सटीक रूप से दिखाती हो. साथ ही, इसके साथ-साथ डीओएम और सीएसएस की बाकी जटिलता को भी हटा देती है. इससे हमें कंपोज़िटिंग और स्क्रोलिंग के एल्गोरिदम को ज़्यादा भरोसे के साथ लागू करने में मदद मिलती है. खास तौर पर:
- संभावित गड़बड़ियों वाली ज्यामिति और दूसरी गणनाओं को एक ही जगह पर रखा जा सकता है.
- प्रॉपर्टी ट्री को बनाने और अपडेट करने से जुड़ी जटिलता को, रेंडरिंग पाइपलाइन स्टेज में अलग-अलग रखा गया है.
- फ़ुल डीओएम स्टेट की तुलना में, प्रॉपर्टी ट्री को अलग-अलग थ्रेड और प्रोसेस पर भेजना ज़्यादा आसान और तेज़ है. इससे, इस्तेमाल के कई उदाहरणों के लिए इनका इस्तेमाल किया जा सकता है.
- इस्तेमाल के जितने ज़्यादा उदाहरण होंगे सबसे ऊपर बनी ज्यामिति कैश मेमोरी से हमें उतने ही ज़्यादा नतीजे मिलेंगे. क्योंकि ये एक-दूसरे की कैश मेमोरी का फिर से इस्तेमाल कर सकती हैं.
रेमिविंगएन, कई कामों के लिए प्रॉपर्टी ट्री का इस्तेमाल करता है, जिनमें ये शामिल हैं:
- पेंट से कंपोज़िटिंग, और मुख्य थ्रेड से कंपोज़िटिंग अलग-अलग की जा रही है.
- एक बेहतर कंपोज़िटिंग / ड्रॉ रणनीति तय करना.
- IntersectionObserver ज्यामिति को मापना.
- ऑफ़स्क्रीन एलिमेंट और जीपीयू टेक्सचर टाइल के लिए, काम से बचने का तरीका.
- पेंट और रास्टर को कुशलता से और सही तरीके से अमान्य किया जा रहा हो.
- Core Web Vitals में, लेआउट में बदलाव और सबसे बड़े कॉन्टेंटफ़ुल पेंट को मेज़र करना.
हर वेब दस्तावेज़ में चार अलग-अलग प्रॉपर्टी ट्री होते हैं: ट्रांसफ़ॉर्म, क्लिप, इफ़ेक्ट, और स्क्रोल.(*) ट्रांसफ़ॉर्म ट्री, सीएसएस ट्रांसफ़ॉर्म और स्क्रोलिंग को दिखाता है. (स्क्रोल ट्रांसफ़ॉर्म को 2D ट्रांसफ़ॉर्म मैट्रिक्स के तौर पर दिखाया जाता है.) क्लिप ट्री में, ओवरफ़्लो क्लिप दिखती है. इफ़ेक्ट ट्री में अन्य सभी विज़ुअल इफ़ेक्ट शामिल होते हैं: ओपैसिटी, फ़िल्टर, मास्क, ब्लेंड मोड, और क्लिप-पाथ जैसी अन्य तरह की क्लिप. स्क्रोल ट्री, स्क्रोल करने के बारे में जानकारी दिखाता है, जैसे कि चेन को एक साथ कैसे स्क्रोल किया जाता है. इसकी ज़रूरत कंपोज़िटर थ्रेड पर स्क्रोल करने के लिए होती है. प्रॉपर्टी ट्री का हर नोड, DOM एलिमेंट के ज़रिए लागू किए गए स्क्रोल या विज़ुअल इफ़ेक्ट को दिखाता है. अगर कई इफ़ेक्ट होते हैं, तो एक ही एलिमेंट के लिए हर ट्री में एक से ज़्यादा प्रॉपर्टी ट्री नोड हो सकते हैं.
हर ट्री की टोपोलॉजी, डीओएम की खास जानकारी की तरह है. उदाहरण के लिए, अगर ओवरफ़्लो क्लिप वाले तीन डीओएम एलिमेंट हैं, तो क्लिप ट्री नोड तीन होंगे. क्लिप ट्री का स्ट्रक्चर, ओवरफ़्लो क्लिप के बीच ब्लॉक संबंध के हिसाब से चलेगा. पेड़ों के बीच में लिंक भी होते हैं. ये लिंक, नोड के रिलेटिव डीओएम हैरारकी और उनके ऐप्लिकेशन के क्रम को दिखाते हैं. उदाहरण के लिए, अगर किसी डीओएम एलिमेंट पर कोई ट्रांसफ़ॉर्म, फ़िल्टर वाले दूसरे डीओएम एलिमेंट के नीचे है, तो बेशक फ़िल्टर से पहले ट्रांसफ़ॉर्म ऐक्शन लागू होता है.
हर डीओएम एलिमेंट का एक प्रॉपर्टी ट्री स्टेट होता है, जो चार टपल (ट्रांसफ़ॉर्म, क्लिप, इफ़ेक्ट, स्क्रोल) होता है. यह उस एलिमेंट पर लागू होने वाले एंसेस्टर क्लिप, ट्रांसफ़ॉर्म, और इफ़ेक्ट ट्री नोड के बारे में बताता है. यह बहुत आसान है, क्योंकि इस जानकारी से हमें उस एलिमेंट पर लागू होने वाली क्लिप, ट्रांसफ़ॉर्म, और इफ़ेक्ट की सूची और उस क्रम में ठीक से पता होता है. इससे हमें यह पता चलता है कि वह स्क्रीन पर कहां है और उसे कैसे बनाया जा सकता है.
उदाहरण
(सोर्स)
<html>
<div style="overflow: scroll; width: 100px; height: 100px;">
<iframe style="filter: blur(3px);
transform: rotateZ(1deg);
width: 100px; height: 300px"
id="one" srcdoc="iframe one"></iframe>
</div>
<iframe style="top:200px;
transform: scale(1.1) translateX(200px)" id=two
srcdoc="iframe two"></iframe>
</html>
पिछले उदाहरण (जो शुरुआती जानकारी में दिए गए उदाहरण से थोड़ा अलग है) में, जनरेट किए गए प्रॉपर्टी ट्री के मुख्य एलिमेंट यहां दिए गए हैं:
सूचियों और पेंट के हिस्सों को दिखाएं
किसी डिसप्ले आइटम में लो-लेवल ड्रॉइंग कमांड (यहां देखें) शामिल होते हैं, जिन्हें Skia की मदद से रास्टराइज़ किया जा सकता है. डिसप्ले आइटम आम तौर पर आसान होते हैं. इनमें ड्रॉइंग करने के लिए कुछ निर्देश दिए जाते हैं, जैसे कि बॉर्डर या बैकग्राउंड बनाना. डिसप्ले आइटम की सूची बनाने के लिए, सीएसएस पेंटिंग ऑर्डर के बाद पेंट ट्री, लेआउट ट्री और उससे जुड़े फ़्रैगमेंट के ऊपर फिर से चलता है.
उदाहरण के लिए:
<div id="green" style="background:green; width:80px;">
Hello world
</div>
<div id="blue" style="width:100px;
height:100px; background:blue;
position:absolute;
top:0; left:0; z-index:-1;">
</div>
यह एचटीएमएल और सीएसएस नीचे दी गई डिसप्ले सूची बनाएगा, जिसमें हर सेल एक डिसप्ले आइटम है:
व्यू का बैकग्राउंड | #blue बैकग्राउंड |
#green बैकग्राउंड |
#green इनलाइन टेक्स्ट |
---|---|---|---|
drawRect , जिसका साइज़ 800x600 है और जो सफ़ेद रंग का है. |
drawRect की पोज़िशन 0,0 है और इसका साइज़ 100x100 है. इसका रंग नीला है. |
drawRect , जिसका साइज़ 80x18 है, जिसकी पोज़िशन 8,8 है और रंग हरा है. |
drawTextBlob की पोज़िशन 8,8 है और टेक्स्ट "नमस्ते वर्ल्ड" टेक्स्ट है. |
डिसप्ले आइटम की सूची को आगे के क्रम में रखा गया है. ऊपर दिए गए उदाहरण में, हरा div DOM क्रम में नीले div से पहले है, लेकिन CSS पेंट क्रम के लिए यह ज़रूरी है कि ऋणात्मक z-index नीला div, (चरण 3) हरे div (चरण 4.1 से पहले पेंट हो. डिसप्ले आइटम मोटे तौर पर सीएसएस पेंट ऑर्डर स्पेसिफ़िकेशन के ऐटॉमिक स्टेप से मेल खाते हैं. एक ही डीओएम एलिमेंट से कई डिसप्ले आइटम बन सकते हैं, जैसे कि किस तरह #green में बैकग्राउंड के लिए डिसप्ले आइटम और इनलाइन टेक्स्ट के लिए दूसरा डिसप्ले आइटम मौजूद है. सीएसएस पेंट ऑर्डर स्पेसिफ़िकेशन की पूरी जटिलता दिखाने के लिए, जानकारी का यह स्तर ज़रूरी है. जैसे, नेगेटिव मार्जिन से बनाया गया इंटरलीविंग:
<div id="green" style="background:green; width:80px;">
Hello world
</div>
<div id="gray" style="width:35px; height:20px;
background:gray;margin-top:-10px;"></div>
इससे नीचे दी गई डिसप्ले सूची बनती है, जिसमें हर सेल एक डिसप्ले आइटम होता है:
व्यू का बैकग्राउंड | #green बैकग्राउंड |
#gray बैकग्राउंड |
#green इनलाइन टेक्स्ट |
---|---|---|---|
drawRect , जिसका साइज़ 800x600 है और जो सफ़ेद रंग का है. |
drawRect , जिसका साइज़ 80x18 है, जिसकी पोज़िशन 8,8 है और रंग हरा है. |
8,16 पोज़िशन पर, 35x20 साइज़ वाला drawRect और स्लेटी रंग. |
drawTextBlob की पोज़िशन 8,8 है और टेक्स्ट "नमस्ते वर्ल्ड" टेक्स्ट है. |
डिसप्ले आइटम सूची को सेव किया जाता है और बाद के अपडेट के ज़रिए फिर से इस्तेमाल किया जाता है. अगर पेंट ट्री के चलने के दौरान लेआउट ऑब्जेक्ट में कोई बदलाव नहीं हुआ, तो इसके डिसप्ले आइटम पिछली सूची से कॉपी किए जाते हैं. एक अतिरिक्त ऑप्टिमाइज़ेशन, सीएसएस पेंट ऑर्डर स्पेसिफ़िकेशन की प्रॉपर्टी पर निर्भर करता है: कॉन्टेक्स्ट को स्टैकिंग करना. अगर स्टैकिंग के कॉन्टेक्स्ट में कोई लेआउट ऑब्जेक्ट नहीं बदला गया है, तो पेंट ट्री वॉक, स्टैकिंग के कॉन्टेक्स्ट को छोड़ देता है और डिसप्ले आइटम के पूरे क्रम को कॉपी करता है.
पेंट ट्री की वॉक के दौरान, प्रॉपर्टी ट्री की मौजूदा स्थिति को बनाए रखा जाता है और डिसप्ले आइटम की सूची को उन डिसप्ले आइटम के "कई हिस्सों" में ग्रुप किया जाता है जिनकी प्रॉपर्टी ट्री की स्थिति एक जैसी होती है. यह नीचे दिए गए उदाहरण में दिखाया गया है:
<div id="scroll" style="background:pink; width:100px;
height:100px; overflow:scroll;
position:absolute; top:0; left:0;">
Hello world
<div id="orange" style="width:75px; height:200px;
background:orange; transform:rotateZ(25deg);">
I'm falling
</div>
</div>
इससे नीचे दी गई डिसप्ले सूची बनती है, जिसमें हर सेल एक डिसप्ले आइटम होता है:
व्यू का बैकग्राउंड | #scroll बैकग्राउंड |
#scroll इनलाइन टेक्स्ट |
#orange बैकग्राउंड |
#orange इनलाइन टेक्स्ट |
---|---|---|---|---|
drawRect , जिसका साइज़ 800x600 है और जो सफ़ेद रंग का है. |
drawRect , जिसका साइज़ 100x100 है, यानी कि 0,0 है और जिसका रंग गुलाबी है. |
drawTextBlob की पोज़िशन 0,0 है और टेक्स्ट में "नमस्ते दुनिया" लिखा जाता है. |
drawRect , जिसका साइज़ 75x200 है, जिसकी पोज़िशन 0,0 है और रंग नारंगी है. |
drawTextBlob की पोज़िशन 0,0 है और टेक्स्ट में "मैं गिर रहा/रही हूँ". |
इसके बाद, प्रॉपर्टी ट्री और पेंट के हिस्सों को ट्रांसफ़ॉर्म करें (छोटा करने के लिए आसान तरीका):
पेंट के हिस्सों की क्रम वाली सूची, डिसप्ले आइटम के ग्रुप और प्रॉपर्टी ट्री की स्थिति होती है. यह रेंडरिंग पाइपलाइन के लेयराइज़ चरण के इनपुट के तौर पर काम करती है. पेंट के हिस्सों की पूरी सूची को एक कंपोज़िट की गई लेयर में मर्ज किया जा सकता है और एक साथ रास्टराइज़ किया जा सकता है. हालांकि, इसके लिए हर बार उपयोगकर्ता स्क्रोल करने पर महंगे रास्टराइज़ेशन की ज़रूरत होती है. हर पेंट चंक के लिए एक कंपोज़िट लेयर बनाई जा सकती है और री-रास्टराइज़ेशन से बचने के लिए अलग-अलग रास्टराइज़ किया जा सकता है, लेकिन इससे जीपीयू मेमोरी जल्दी खत्म हो जाएगी. लेयर बनाने के चरण में, जीपीयू मेमोरी के बीच संतुलन बनाना पड़ता है और चीज़ें बदलने पर लागत कम होती है. एक अच्छा सामान्य तरीका यह है कि डिफ़ॉल्ट रूप से कई हिस्सों को मर्ज किया जाए और उन पेंट हिस्सों को मर्ज न किया जाए जिनमें प्रॉपर्टी ट्री की स्थितियां हैं और जिनके कंपोज़िटर थ्रेड पर बदलाव होने की उम्मीद है. जैसे, कंपोज़िटर-थ्रेड स्क्रोलिंग या कंपोज़िटर-थ्रेड ट्रांसफ़ॉर्म ऐनिमेशन के साथ.
ऊपर दिए गए उदाहरण में, दो कंपोज़िट लेयर बनाई जानी चाहिए:
- ड्रॉइंग के निर्देशों वाली 800x600 कंपोज़िट लेयर:
drawRect
, जिसका साइज़ 800x600 और सफ़ेद रंग हैdrawRect
, जिसका साइज़ 100x100 है, जिसकी पोज़िशन 0,0 है और रंग गुलाबी है
- एक 144x224 कंपोज़िट लेयर, जिसमें ड्रॉइंग के निर्देश होते हैं:
drawTextBlob
की पोज़िशन 0,0 है और टेक्स्ट में "नमस्ते दुनिया" लिखा जाता है- 0,18 का अनुवाद करो
rotateZ(25deg)
drawRect
, जिसका साइज़ 75x200 है, जिसकी पोज़िशन 0,0 है और रंग नारंगी हैdrawTextBlob
की स्थिति 0,0 है और टेक्स्ट में "मैं गिर रहा/रही हूं" लिखा है
अगर उपयोगकर्ता #scroll
को स्क्रोल करता है,
तो दूसरी कंपोज़िट की गई लेयर मूव कर दी जाती है. हालांकि, रास्टराइज़ेशन की ज़रूरत नहीं होती.
उदाहरण के लिए, प्रॉपर्टी ट्री के पिछले सेक्शन में, पेंट के छह हिस्से हैं. प्रॉपर्टी ट्री की उनकी (ट्रांसफ़ॉर्म, क्लिप, इफ़ेक्ट, स्क्रोल) स्थितियों के साथ, वे ये हैं:
- दस्तावेज़ का बैकग्राउंड: दस्तावेज़ स्क्रोल, दस्तावेज़ की क्लिप, रूट, दस्तावेज़ का स्क्रोल.
- div के लिए हॉरिज़ॉन्टल, वर्टिकल, और स्क्रोल करके कोना (तीन अलग-अलग पेंट चंक):
दस्तावेज़ स्क्रोल करना, दस्तावेज़ की क्लिप,
#one
ब्लर, दस्तावेज़ स्क्रोल. - Iframe
#one
:#one
घुमाएं, ओवरफ़्लो स्क्रोल क्लिप,#one
धुंधला करें, div स्क्रोल. - Iframe
#two
:#two
स्केल, दस्तावेज़ क्लिप, रूट, दस्तावेज़ स्क्रोल.
कंपोज़िटर फ़्रेम: सरफ़ेस, रेंडर सर्फ़ेस और जीपीयू टेक्सचर टाइल
ब्राउज़र और रेंडर करने की प्रोसेस, कॉन्टेंट के रास्टराइज़ेशन को मैनेज करती हैं. इसके बाद, स्क्रीन पर प्रज़ेंटेशन के लिए कंपोज़िटर फ़्रेम को Viz प्रोसेस में सबमिट करती हैं. कंपोज़िटर फ़्रेम यह दिखाते हैं कि रास्टराइज़ किए गए कॉन्टेंट को एक साथ कैसे स्टिच करें और जीपीयू का इस्तेमाल करके, बेहतर तरीके से कैसे ड्रॉ करें.
टाइल
सिद्धांत के तौर पर, रेंडर प्रोसेस या ब्राउज़र प्रोसेस कंपोज़िटर, पिक्सल को रेंडरर व्यूपोर्ट के पूरे साइज़ के एक टेक्सचर में रास्टर कर सकता है और उस टेक्सचर को Viz में सबमिट कर सकता है. इसे दिखाने के लिए, डिसप्ले कंपोज़िटर को सिर्फ़ उस एक टेक्सचर के पिक्सल को फ़्रेम बफ़र में सही जगह पर कॉपी करना होगा (उदाहरण के लिए, स्क्रीन). हालांकि, अगर वह कंपोज़िटर एक भी पिक्सल को अपडेट करना चाहता है, तो उसे पूरे व्यूपोर्ट को फिर से रास्टराइज़ करना होगा और Viz पर नया टेक्सचर सबमिट करना होगा.
इसके बजाय, व्यूपोर्ट को टाइल में बांट दिया गया है. अलग जीपीयू टेक्सचर टाइल, हर टाइल को व्यूपोर्ट के हिस्से के लिए रास्टराइज़ किए गए पिक्सल के साथ बैक करती है. इसके बाद रेंडरर अलग-अलग टाइल को अपडेट कर सकता है या मौजूदा टाइल की स्क्रीन पर सिर्फ़ उसकी जगह भी बदल सकता है. उदाहरण के लिए, किसी वेबसाइट को स्क्रोल करते समय, मौजूदा टाइल की जगह ऊपर की ओर शिफ़्ट हो जाएगी और कभी-कभी पेज पर और नीचे कॉन्टेंट के लिए नई टाइल को रास्टराइज़ करने की ज़रूरत होगी.
![चार टाइल.](https://developer.chrome.com/static/docs/chromium/renderingng-data-structures/image/four-tiles-b115857a2f73.jpg?authuser=7&hl=hi)
क्वाड और सर्फ़ेस
जीपीयू टेक्सचर टाइल, एक खास तरह के क्वाड होती हैं. ये किसी न किसी कैटगरी के टेक्सचर के लिए, एक खास नाम है. क्वाड, इनपुट टेक्सचर की पहचान करता है. साथ ही, इसमें विज़ुअल इफ़ेक्ट को बदलने और लागू करने का तरीका भी बताता है. उदाहरण के लिए, कॉन्टेंट की सामान्य टाइल में एक ट्रांसफ़ॉर्म होता है. इससे टाइल ग्रिड में उनके x और y की पोज़िशन को पता चलता है.
इन रास्टराइज़ की गई टाइल को रेंडर पास में रैप किया जाता है, जो क्वाड की सूची होती है. रेंडर पास में पिक्सल की कोई जानकारी नहीं होती. इसके बजाय, इसमें यह निर्देश दिए गए होते हैं कि सही पिक्सल आउटपुट पाने के लिए, हर क्वाड को कहां और कैसे ड्रॉ करें. हर जीपीयू टेक्सचर टाइल के लिए, ड्रॉ क्वाड होता है. डिसप्ले कंपोज़िटर को बस क्वाड की सूची को दोहराना पड़ता है और रेंडर पास के लिए मनचाहा पिक्सल आउटपुट देने के लिए हर एक को खास विज़ुअल इफ़ेक्ट के साथ ड्रॉ करना पड़ता है. रेंडर पास के लिए, ड्रॉ क्वाड कंपोज़िट करना जीपीयू पर बेहतर तरीके से किया जा सकता है. ऐसा इसलिए, क्योंकि जिन विज़ुअल इफ़ेक्ट की अनुमति है उन्हें सीधे जीपीयू सुविधाओं से मैप करने के लिए चुना जाता है.
रास्टराइज़ की गई टाइल के अलावा, कई तरह के ड्रॉ क्वाड भी होते हैं. उदाहरण के लिए, सॉलिड कलर ड्रॉ क्वाड होते हैं, जो किसी टेक्सचर का इस्तेमाल करके नहीं बनाए जाते हैं. इसके अलावा, वीडियो या कैनवस जैसे नॉन-टाइल टेक्सचर के लिए, टेक्सचर ड्रॉ क्वाड होते हैं.
एक कंपोज़िटर फ़्रेम के लिए, एक और कंपोज़िटर फ़्रेम एम्बेड करना भी मुमकिन है. उदाहरण के लिए, ब्राउज़र कंपोज़िटर, ब्राउज़र यूज़र इंटरफ़ेस (यूआई) वाला कंपोज़िटर फ़्रेम और एक खाली रेक्टैंगल बनाता है. इसमें कंपोज़िटर का कॉन्टेंट एम्बेड किया जाएगा. इसका एक और उदाहरण है साइट आइसोलेटेड iframe. यह एम्बेड करने की प्रोसेस प्लैटफ़ॉर्म से पूरी की जाती है.
जब कोई कंपोज़िटर फ़्रेम सबमिट करता है, तो उसके साथ एक आइडेंटिफ़ायर जुड़ा होता है. इसे surface ID कहा जाता है. इसकी मदद से, कंपोज़िटर फ़्रेम को रेफ़रंस के तौर पर एम्बेड किया जा सकता है. किसी खास सरफ़ेस आईडी के साथ सबमिट किया गया सबसे नया कंपोज़िटर फ़्रेम, Viz के ज़रिए सेव किया जाता है. एक और कंपोज़िटर फ़्रेम इसे सर्फ़ेस ड्रॉ क्वाड के ज़रिए देख सकता है, और इसलिए विज़ को पता है कि क्या ड्रॉ करना है. (ध्यान दें कि सरफ़ेस ड्रॉ क्वाड में सिर्फ़ सरफ़ेस आईडी होते हैं, टेक्सचर नहीं.)
इंटरमीडिएट रेंडर पास
कुछ विज़ुअल इफ़ेक्ट, जैसे कि कई फ़िल्टर या ऐडवांस ब्लेंड मोड के लिए यह ज़रूरी होता है कि बीच के टेक्सचर के लिए दो या उससे ज़्यादा क्वाड दिखें. इसके बाद, जीपीयू पर डेस्टिनेशन बफ़र को इंटरमीडिएट टेक्सचर के तौर पर इस्तेमाल किया जाता है या किसी दूसरे इंटरमीडिएट टेक्सचर का इस्तेमाल किया जाता है. ऐसा करने पर, विज़ुअल इफ़ेक्ट को एक ही समय पर लागू किया जाता है. इसकी अनुमति देने के लिए, एक कंपोज़िटर फ़्रेम में असल में रेंडर पास की सूची होती है. एक रूट रेंडर पास हमेशा होता है, जिसे सबसे आखिर में बनाया जाता है और जिसका डेस्टिनेशन फ़्रेम बफ़र से मेल खाता है. ऐसे कई और भी हो सकते हैं.
एक से ज़्यादा रेंडर पास होने की संभावना, "रेंडर पास" नाम के बारे में बताती है. हर पास को जीपीयू पर क्रम से लागू करना होता है, कई "पास" में. वहीं एक पास को बड़े पैमाने पर पैरलल जीपीयू से बनाई जा सकती है.
एक साथ दिखाना
विज़ में एक से ज़्यादा कंपोज़िटर फ़्रेम सबमिट किए जाते हैं और उन्हें स्क्रीन पर एक साथ खींचना होता है. ऐसा एग्रीगेशन के चरण से किया जाता है, जो उन्हें सिंगल, एग्रीगेटेड कंपोज़िटर फ़्रेम में बदल देता है. एग्रीगेशन, सरफ़ेस ड्रॉ क्वाड को उनके बताए गए कंपोज़िटर फ़्रेम से बदल देता है. यह बीच में दिखने वाले ग़ैर-ज़रूरी टेक्स्चर या ऑफ़स्क्रीन कॉन्टेंट को ऑप्टिमाइज़ करने का भी मौका है. उदाहरण के लिए, कई मामलों में, किसी साइट के लिए कंपोज़िटर फ़्रेम को अलग किए गए iframe के लिए अपने इंटरमीडिएट टेक्सचर की ज़रूरत नहीं होती है. साथ ही, उसे सही ड्रॉ क्वाड की मदद से सीधे फ़्रेम बफ़र में ले जाया जा सकता है. एग्रीगेशन फ़ेज़ ऐसे ऑप्टिमाइज़ेशन का पता लगाता है और उन्हें उस ग्लोबल जानकारी के आधार पर लागू करता है जो अलग-अलग रेंडर कंपोज़िटर के पास नहीं होती.
उदाहरण
यहां ऐसे कंपोज़िटर फ़्रेम दिए गए हैं जो इस पोस्ट की शुरुआत से उदाहरण दिखाते हैं.
foo.com/index.html
प्लैटफ़ॉर्म: id=0- रेंडर पास 0: आउटपुट पाने के लिए ड्रॉ करें.
- रेंडर पास ड्रॉ क्वाड: तीन पिक्सल ब्लर के साथ ड्रॉ करें और रेंडर पास 0 में क्लिप करें.
- रेंडर पास 1:
#one
iframe की टाइल कॉन्टेंट के लिए क्वाड बनाएं. हर आइटम के लिए x और y पोज़िशन का इस्तेमाल करें.
- रेंडर पास 1:
- सरफ़ेस ड्रॉ क्वाड: आईडी 2 के साथ, स्केल और ट्रांसलेशन ट्रांसफ़ॉर्म के साथ बनाया गया है.
- रेंडर पास ड्रॉ क्वाड: तीन पिक्सल ब्लर के साथ ड्रॉ करें और रेंडर पास 0 में क्लिप करें.
- रेंडर पास 0: आउटपुट पाने के लिए ड्रॉ करें.
- ब्राउज़र के यूज़र इंटरफ़ेस (यूआई) का सरफ़ेस: आईडी=1
- रेंडर पास 0: आउटपुट पाने के लिए ड्रॉ करें.
- ब्राउज़र के यूज़र इंटरफ़ेस (यूआई) के लिए क्वाड बनाएं (टाइल भी किया गया)
- रेंडर पास 0: आउटपुट पाने के लिए ड्रॉ करें.
bar.com/index.html
प्लैटफ़ॉर्म: आईडी=2- रेंडर पास 0: आउटपुट पाने के लिए ड्रॉ करें.
#two
iframe की सामग्री के लिए क्वाड बनाएं और हर एक के लिए x और y की जगह रखें.
- रेंडर पास 0: आउटपुट पाने के लिए ड्रॉ करें.
यूना क्रवेट्स के इलस्ट्रेशन.