كيف يرسم المتصفح. تقرير ياندكس

حتى وقت قريب ، عملت في فريق Yandex.Browser وقدمت عرضًا تقديميًا في مؤتمر YaTalks في أعقاب هذه التجربة. كان التقرير يدور حول ما لدى المستعرض أسفل الغطاء وكيف تتحول صفحاتك إلى وحدات بكسل على الشاشة. الواجهة الأمامية الدنيا ، فقط الدواخل في المتصفح ، المتشددين فقط.



- مرحبا بالجميع ، اسمي كوستيا. من المستغرب ، الآن أنا أعمل في فريق شبكة افتراضية Yandex.Cloud. قبل ذلك ، عملت في فريق Browser منذ أكثر من خمس سنوات ، لذلك سأتحدث اليوم عن أشياء شائعة بيننا وبينك.

كما قد تخمن ، أنا لا أفهم جيدًا في المقدمة. إذا تحدثت معي حول React أو أي شيء آخر كهذا ، ربما لن أفهمك. لكنني فعلت الكثير من الأشياء في المتصفح: فك تشفير الفيديو ، منطق العمل. بما في ذلك قضيت الكثير من الوقت في القيام بأشياء مختلفة في تقديم المتصفح. اليوم ، سيكون لدينا مثل هذا البرنامج التعليمي حول الجهاز الداخلي للمتصفح. سأحاول الاطلاع على أكثر الأشياء إثارة للاهتمام التي قمنا بها في Yandex.Browser أو Google في Chromium.



إذا تحدثنا عن العرض في المتصفح ، فهذا شيء معقد للغاية ، والذي يتكون من عدد كبير من المكونات. بادئ ذي بدء ، يجب عليك تنزيل الموارد لإظهارها. ثم يتعين عليك تحليلها ، وبناء شجرة DOM ، والأنماط ، والتخطيطات ، وما إلى ذلك. النقاط الثلاث الأولى على الأرجح مألوفة بالنسبة لك. سيتم تكريس تقريري بشكل أكبر للأجزاء الثلاثة الأخرى: الرسم والتنقيط والتركيب - ما يحدث تحت الغطاء عندما تكون قد قمت بالفعل بكتابة التصميم. بالكلمات فقط يمكن أن يبدو الأمر وكأنه يتعلق بنفس الشيء - في الواقع ، هذه مكونات مختلفة تمامًا.



لنبدأ بالطلاء والتركيب. ما هذا كله؟ دعنا نعود منذ عدة سنوات ، عندما لم تكن الويب معقدة كما هي الآن ، عندما لم تكن هناك جميع أنواع الرسوم المتحركة ثلاثية الأبعاد ، CSS وأشياء أخرى. كيف ثم وجه المستعرض؟ تخيل أن لديك صفحتك ، عليها بعض العناصر الرائعة ، الصور ، إلخ. قام المستعرض برسم كل هذا على نسيج ضخم واحد ، في كتلة كبيرة من الذاكرة. لقد كان يعرف كيفية رسم كل عنصر ، وإذا كان لدينا أي تغييرات ، فسيتم تسليط الضوء عليها باللون الأصفر ، وقد حدث شيء مثل التالي.

قام المستعرض بتجميعها في المناطق المشار إليها هنا باللون الأزرق. لقد حدث تغيير في هذا المجال ، دعنا نعيد رسمه. تم إعادة رسم كل شيء في هذا المجال ونسخه إلى الملمس.

عملت لنفسها. ثم توصل الأشخاص الأذكياء إلى الرسوم المتحركة ثلاثية الأبعاد لـ CSS وأشياء أخرى. يمكن أن يكون لدينا الكثير من الاداءات في أماكن مختلفة. إذا قمنا بتدوير عمود واحد ، فإن إعادة رسم الكعكة الكاملة للعناصر الموجودة تحتها ليست فعالة للغاية.



ثم قرر أشخاص أذكياء آخرون إعادة الأمر قليلاً. لدينا نوع من شجرة DOM ، بنيناها في الذاكرة. هذه كائنات زائدة ، تتم مقارنتها بالتخطيط الذي كتبته.



ثم يبدأ السحر في الحدوث. يحول المستعرض شجرة DOM بأكملها إلى شجرة Render Object. يعرف هذا الشيء كيفية رسم كل عنصر DOM معين. أي أنها تعرف ما يجب القيام به حتى يظهر شيء ما على الشاشة بدلاً من الشجرة أو عنصر P.



الشجرة التالية هي شجرة الطبقات. ما هذا يمكن ربط كل عنصر من عناصرنا بأي طبقة واحدة ، ويمكن أن تحتوي طبقة التجسيد الواحدة على عدة كائنات في وقت واحد. لماذا يتم ذلك؟ هذا يظهر بشكل جيد للغاية هنا. نقوم بإنشاء مجموعة من الطبقات ، لكل منها عناصر معينة. الآن ، لنفترض أن هناك شيئًا ما يتغير على إحدى الطبقات - تظهر رسوم متحركة ، ويطير عنصر الطابع. بعد ذلك ، نقوم بإعادة رسم طبقة واحدة فقط ، والباقي ، على سبيل المثال ، الخلفية لم يتغير. ثم نقوم ببساطة بلصقها في مواد مركبة وفي المخرجات نحصل على الصورة النهائية - الإطار الحالي للرسوم المتحركة.



هناك مجموعة ثابتة من الأسباب لإنشاء طبقات جديدة. على سبيل المثال ، يتم إنشاء طبقة لتقديم 3D CSS للرسوم المتحركة ، قماش ، عنصر فيديو - بشكل عام ، شيء متعلق بالرسوم المتحركة الثقيلة ، ومناسبة لإعادة الرسم بشكل منفصل عن جميع المحتويات الأخرى.



لكن هذا النهج لديه العديد من المشاكل. الآن تحتاج إلى تشغيل الوقود. فكر فيما سيتم تصويره هنا؟ لا يوجد سوى عنصرين.



هنا. على الرغم من أنه يبدو أن العناصر تقع واحدة تلو الأخرى. لماذا قماش تطير؟ في بلدنا ، يتم ترتيبهم بالتسلسل ؛ لم أقم بتعيين أي ترتيب.



دعونا تعقيد. هنا لدينا div آخر ، مثل هذا.



بشكل عام ، السلوك المتوقع. لدينا div على الجزء العلوي من div ، لكن قماش لسبب ما في الأعلى. السحر! حسنًا ، دعنا نعقد هذا المثال مرة أخرى.



لقد تغير سطر واحد بالضبط ، أضفت التحويل.



والآن لدينا كل شيء موجود بشكل صحيح - على الأقل من ناحية قماش و div. ولكن لا يزال هذا div موجودًا أدناه ، على الرغم من أنه كان العنصر التالي في تخطيطنا.

هذا هو ما يسمى علة التركيب الأساسية. إذا كنت تبحث عن تعقب Chromium ، فسترى مجموعة من الأخطاء المرتبطة بأحد القديم. ويسمى ذلك.



إذن ماذا حدث؟ كما قلت ، يتم تقديم بعض العناصر على طبقة التجسيد ، بعضها لا. يتم رسمها مع بعض الآخرين. حدث ما يلي: تظل عناصر div في نفس طبقة الخلفية. تعطل قماش لطبقة منفصلة. ويتم تنفيذ الأمر z فقط بين الطبقات. نظرًا لحقيقة أن لدينا خلفية و div في طبقة وقماش في طبقة أخرى ، نحصل على خطأ: قماش يتداخل مع div.

ولكن بمجرد نقل عنصر div إلى طبقة منفصلة ويبدأ في استخدام الترتيب z بشكل طبيعي ، يبدأ أيضًا في فهم من يقف وراء من. وهنا يتم تقديم كل شيء "طبيعي".



واحدة من آخر المبادرات التي تم تطويرها منذ عدة سنوات هي ما يسمى Paint Slimming Paint ، والذي يجب إصلاحه. معناها هو أننا بحاجة إلى فصل اللوحة عن التدريج ، أي فهم ما يجب القيام به لرسم هذه العناصر ، من كيفية تكوينها مع بعضها البعض. إذا كان لدينا مثل هذا التصميم البسيط ، فإنه يتحول إلى شيء من هذا القبيل. هناك قائمة بسيطة من الأوامر التي تحتاج إلى القيام بها من أجل الحصول على محتوى الصفحة. وإذا عدنا إلى هذا المثال ، فسوف يبدو مثل هذا.



لقد قلنا: هذا الرسام من أجلك ، إليك المحتوى الخاص بك - من فضلك أعطني شيئًا. إنه يوفر قائمة للتجسيد ، والتي تذهب إلى Compositor ، ويفهم Compositor كيفية تقسيم كل المحتوى إلى طبقات بحيث تكون موجودة عادة بالنسبة لبعضها البعض.

وإذا لم تكن قد لاحظت ، فهذه لقطة شاشة من Chrome. لقد قمت بذلك منذ حوالي أسبوعين ، أي أن الخطأ لا يزال حياً. المشروع لم ينته بعد ، وهو الآن في مرحلة التطوير.



بمعنى ، يمكن للمؤلف من هذه القائمة وبعض المعرفة السرية التي يمر بها plink أن يفهموا كيفية وضعها بشكل كامل في طبقات.



إلى جانب حقيقة أن هذا النهج سيصلح هذا الخطأ بشكل أساسي ، فإننا نحصل أيضًا على تغييرات رخيصة إلى حد ما في التقديم. افترض أن لدينا قائمة بأوامر السحب والتغييرات تحدث - دعنا نقول أن يترك العنصر ب ، يضاف العنصر E. بعد ذلك يمكننا ببساطة الاحتفاظ بالقائمتين معًا دون القلق بشأن الأشجار ، وما إلى ذلك. في المخرجات ، نحصل على قائمة جديدة من العناصر لتقديمها ، وربما قائمة جديدة من الطبقات التي سيتم تجميعها في المستقبل.

كانت هذه قصة قصيرة حول ما يحدث عندما ينفّذ المتصفح Paint ، وما يحدث بعد أن يحاول تكوين طبقات.

دعنا ننتقل إلى موضوع آخر: التنقيط. فقط في Rasterization في Yandex.Browser ، تم القيام بالكثير من الأشياء ، وفعلت هذا أيضًا. ما معنى التنقيط؟ عند إخراج المرحلة السابقة ، عندما قمنا بالطلاء ، هناك قائمة بالأوامر التي يجب أن ننفذها للحصول على نوع من الصورة. التنقيط هو تحويل قائمة الأوامر إلى وحدات بكسل حقيقية.





إذا قمت بفتح علامة التبويب المزيد من الأدوات → التقديم في مفتش المتصفح ، فهناك حدود لطبقة اختيار. وترى فقط مثل هذه الشبكة. ما الذي يحدث هنا؟ عندما يقوم المستعرض برسم الصفحة ، فإنه لا يقوم بالأمر بالكامل. يأخذ المستعرض كل طبقة ويقسمها إلى عدد معين من هذه المربعات الصغيرة. تاريخيا ، حجمها 256 × 256 بكسل. وهذا هو ، كل طبقة تنقسم إلى العديد من القوام منفصلة. ثم يتم رسم محتوى التجانب الحالي على كل نسيج ، ثم يتم لصقها جميعًا في نسيج كبير واحد.



إنها تساعد كثيرا. بادئ ذي بدء ، لا يمكننا إعادة رسم سوى تلك البلاط التي تغيرت. ولكنه يسمح لنا أيضًا بتحديد أولويات العرض. وهذا هو ، أولاً وقبل كل شيء ، تلك القطع التي يراها المستخدم ، ما يسمى إطار العرض ، يجب رسمها. ثم علينا أن نرسم الحدود قريبا ، وهذا هو ما حول منفذ العرض. التالي هو اتجاه التمرير: إذا تم التمرير لأسفل ، فنحن نرسم لأسفل قدر الإمكان. إذا يصل - ارسم قدر الإمكان. إذا كان لا يزال لدينا حصة من الذاكرة ، فسوف نرسم شيئًا آخر ، ولكن ليس حقيقة أنه سيبقى في هذه المرحلة.



حتى نحصل على تحديث محتوى رخيصة إلى حد ما على الصفحة. لنفترض أننا أخذنا الإطار الحالي وأن المستخدم قام بتعطيل شيء ما - على سبيل المثال ، النص المميز. ثم نرسم فقط تلك البلاط التي تغيرت.



أي أن البلاط الأخضر هو تلك التي تبقى من التجسيد السابق ، والأحمر الذي أعيد رسمه. لكن هذا النهج له مزايا أخرى.



يمكننا أن نفعل - وفعل Chrome ذلك - ما يسمى بتحسين عمليات إعادة الرسم الصغيرة. افترض أن لديك نوعًا من الخفقان أو المؤشر أو أي شيء آخر كأنك تقوم بعملية إعادة رسم صغيرة في مستطيل صغير. ثم نحن لسنا بحاجة لإعادة رسم الساحة بأكملها. هذا منطقي. على سبيل المثال ، إذا يومض المؤشر لدينا ، فسيتم إعادة رسمه فقط. هذا يحفظ إلى حد كبير وحدة المعالجة المركزية.



التحسين المقبل قاموا به. أين يمكن أن يكون هناك عدم كفاءة؟ هل تحول البلاط؟ فكرة جيدة ، لكنني أميل إلى أخرى. هنا مجرد مستطيل أبيض. هذا هو البلاط الأبيض الذي لا يتم رسم بكسل واحد. لكنه نسيج. يستغرق 256 256 بواسطة أربعة بايت من الذاكرة.



تحسين آخر تم اختراعه في Chrome: فلنأخذ هذه التجانبات بلون واحد ، ولا نشفّرها باستخدام مجموعة من البكسلات ، ولكن في الواقع ، مع المنسقين ، الحجم واللون. أصبح الإنترنت الآن مليئًا بالصفحات التي تحتوي على الكثير من المساحات الأحادية للشاشات الكبيرة. ويتم تحسين هذه الصفحات وفقًا لذلك ، حيث نحصل على الكثير من مدخرات الذاكرة.

لقد ذهبنا في Yandex إلى أبعد من ذلك قليلاً وقررنا إجراء تجربة أكثر تحديدًا. أين تعتقد أنه يمكنك توفير أكثر؟

لدينا بلاط. يقع المحتوى الموجود في بعض المناطق الصغيرة - شريط ، كلمة ياندكس. لماذا نحتاج إلى الرسم ككل ، إذا كان المحتوى صغيرًا جدًا ، وكل شيء آخر أحادي اللون؟



ماذا فعلنا؟ هذا ما فعلته بالتحديد. قمنا بتقسيم كل بلاطة إلى خمسة بلاطات. إذا كان المحتوى الموجود في المنتصف فقط ، فإننا نختار نسيج هذا المحتوى فقط لما يتم في الوسط. هنا المنطقة الحمراء. كل شيء آخر نحن رمز بنفس الطريقة - الحجم والإحداثيات واللون.



هذا هو ، على وجه التحديد في هذه الصفحة ، أصبحت كل هذه المناطق الآن غير الملمس. لا يتم استخدام وحدات البايت في الذاكرة ، ولكن ببساطة أوامر حول ما نحتاج إلى رسمه هنا ، تملأ بلون واحد. هذا أعطانا متوسط ​​وفورات حوالي 40 ٪ على ذاكرة GPU لكل مستخدم.



في الصفحات الأكثر تعقيدًا ، يبدو الأمر هكذا. نظرًا لأن الصفحات الأكثر تعقيدًا تستخدم طبقات أكثر ، ولكل طبقة تجانب منفصل ، يمكنك حفظ القليل على أي طبقة.

إذا قمت بتمكين علامة الاختيار هذه الآن ، فلن ترى شبكة من هذه المستطيلات ، ولكنك لن ترى هذه الشبكة.



ما هو ، لماذا البلاط هنا واسعة جدا ، ولماذا هناك عدد قليل منهم؟ المعنى هنا هو على النحو التالي. في Chrome ، اعتقدوا: لماذا لا نقوم فقط بتركيب الأجهزة ، ولكن أيضًا تقديم الأجهزة. ماذا يفعلون؟ لدينا قائمة من الأوامر بشأن ما يجب القيام به: رسم مستطيل ، وملء بالألوان ، وما إلى ذلك. كل هذا يذهب إلى GPU ، بينما يرسم GPU مثل هذا الملمس. إعادة الرسم سريعة جدًا ، لذا يمكن أيضًا جعل البلاط كبيرًا. إليك مقطع فيديو صغير يحتوي على ابن آوى ، لكنه يُظهر جيدًا الميزة التي حدثت على الهواتف نظرًا لحقيقة أن العرض أصبح متسارعًا في الأجهزة. أعتقد أن الفرق هنا واضح للغاية.

يبدو التواصل بين مطوري المتصفح والبائعين الأماميين مفيدًا جدًا بالنسبة لي. هذا لا يحدث في كثير من الأحيان ، لكنه يعطي الكثير من الفوائد. لذلك ، عندما يأتي إلينا زملاءنا من الإدارات الأخرى ويسألوننا كيف يمكننا جعل التخطيط أسرع وأفضل ، فإننا نحاول مساعدتهم وإخبارهم عن الأماكن التي لا يوجد فيها شيء مثالي ويمكنك تسريعها.

ولن أتعب من تكرار نصيحتي. (لن أذكر هنا ، كان هناك تقرير كبير منفصل حول هذا الموضوع - تعليق المؤلف).

هنا قمت بتجميع مجموعة من الروابط المفيدة ، حول التقديم وليس فقط ، ولكن أيضًا حول Yandex.Browser. شكرا لك

Source: https://habr.com/ru/post/ar468165/


All Articles