نظرة من الداخل على متصفح الويب الحديث (الجزء 3)

Mariko Kosaka

آلية عمل عملية التقديم

هذا هو الجزء 3 من سلسلة مكوّنة من 4 أجزاء في المدونة تتناول آلية عمل المتصفّحات. لقد ناقشنا سابقًا بنية العمليات المتعدّدة ومسار التنقّل. في هذه المشاركة، سنلقي نظرة على ما يحدث داخل عملية عرض الصفحة.

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

تعالج عمليات عرض المحتوى محتوى الويب.

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

تتمثل المهمة الأساسية لعملية العرض في تحويل HTML وCSS وJavaScript إلى صفحة ويب يمكن للمستخدِم التفاعل معها.

عملية العارض
الشكل 1: عملية العارض التي تتضمّن سلسلة عمليات رئيسية وسلاسل عمليات وحدات عمل وسلسلة عمليات تركيب وسلسلة عمليات مصفوفة داخل

التحليل

إنشاء عنصر DOM

عندما تتلقّى عملية عرض الصفحة رسالة تأكيد لمسار تنقّل وتبدأ في تلقّي بيانات HTML، تبدأ سلسلة المحادثات الرئيسية في تحليل سلسلة النصوص (HTML) وتحويلها إلى موديل مستند لمستند (DOM).

نموذج كائن المستند (DOM) هو تمثيل داخلي للمتصفّح للصفحة، بالإضافة إلى بنية البيانات وواجهة برمجة التطبيقات التي يمكن لمطوّر الويب التفاعل معها من خلال JavaScript.

يتم تحديد تحليل مستند HTML إلى نموذج عناصر في المستند من خلال معيار HTML. قد تكون لاحظت أنّه لا يحدث خطأ أبدًا عند إرسال ملف HTML إلى متصفّح. على سبيل المثال، علامة HTML صالحة إذا كانت لا تتضمّن علامة الإغلاق </p>. يتم التعامل مع الترميز الخطأ مثل Hi! <b>I'm <i>Chrome</b>!</i> (يتم إغلاق علامة b قبل علامة i) كما لو كنت قد كتبت Hi! <b>I'm <i>Chrome</i></b><i>!</i>. ويعود السبب في ذلك إلى أنّ مواصفات HTML مصمّمة للتعامُل مع هذه الأخطاء بشكل سلس. إذا كنت مهتمًا بمعرفة كيفية تنفيذ هذه الإجراءات، يمكنك الاطّلاع على القسم "مقدّمة عن معالجة الأخطاء والحالات الغريبة في المدقّق" من مواصفات HTML.

تحميل الموارد الفرعية

يستخدم الموقع الإلكتروني عادةً موارد خارجية، مثل الصور وCSS وJavaScript. يجب تحميل هذه الملفات من الشبكة أو ذاكرة التخزين المؤقت. يمكن للسلسلة الرئيسية طلبها واحدًا تلو الآخر عند العثور عليها أثناء التحليل لإنشاء نموذج DOM، ولكن لزيادة السرعة، يتم تشغيل "أداة فحص التحميل المُسبَق" بشكل متزامن. إذا كان هناك عناصر مثل <img> أو <link> في مستند HTML، يلقي الماسح الضوئي لتحميل المهام مسبقًا نظرة على الرموز المميّزة التي ينشئها محلل HTML ويرسل الطلبات إلى سلسلة محادثات الشبكة في عملية المتصفّح.

نموذج العناصر في المستند (DOM)
الشكل 2: سلسلة المهام الرئيسية التي تُحلِّل محتوى HTML وتُنشئ شجرة DOM

يمكن أن تحظر JavaScript عملية التحليل.

عندما يعثر محلّل HTML على علامة <script>، يوقف مؤقتًا تحليل مستند HTML ويجب عليه تحميل رمز JavaScript وتحليله وتنفيذه. لماذا؟ لأنّ JavaScript يمكنها تغيير شكل المستند باستخدام عناصر مثل document.write() التي تغيّر بنية DOM بالكامل (نظرة عامة على نموذج التحليل في مواصفات HTML تتضمّن مخطّطًا بيانيًا رائعًا). لهذا السبب، على منظّم HTML الانتظار إلى أن يتم تنفيذ JavaScript قبل أن يتمكّن من استئناف تحليل ملف HTML. إذا كنت مهتمًا بمعرفة ما يحدث أثناء تنفيذ JavaScript، يقدّم فريق V8 محادثات ومشاركات مدوّنة حول هذا الموضوع.

تقديم تلميح للمتصفّح حول كيفية تحميل الموارد

هناك العديد من الطرق التي يمكن لمطوّري الويب من خلالها إرسال إشارات إلى المتصفّح لتحميل الموارد بشكلٍ جيد. إذا كانت لغة JavaScript لا تستخدم document.write()، يمكنك إضافة سمة async أو defer إلى علامة <script>. بعد ذلك، يحمِّل المتصفّح رمز JavaScript ويشغّله بشكل غير متزامن ولا يحظر التحليل. يمكنك أيضًا استخدام وحدة JavaScript إذا كان ذلك مناسبًا. <link rel="preload"> هي طريقة لإعلام المتصفّح بأنّ المرجع مطلوب بالتأكيد للتنقّل الحالي وأنّك تريد تنزيله في أقرب وقت ممكن. يمكنك الاطّلاع على مزيد من المعلومات حول هذا الموضوع في مقالة منح الأولوية للموارد - مساعدة المتصفّح في ذلك.

احتساب الأنماط

لا يكفي توفُّر نموذج DOM لمعرفة الشكل الذي ستظهر به الصفحة لأنّه يمكننا تصميم عناصر الصفحة باستخدام CSS. تُحلِّل سلسلة المحادثات الرئيسية لغة CSS وتحدِّد النمط المحسوب لكلّ عقدة DOM. هذه هي معلومات عن نوع النمط الذي يتم تطبيقه على كل عنصر استنادًا إلى أدوات اختيار CSS. يمكنك الاطّلاع على هذه المعلومات في قسم computed ضمن "أدوات مطوّري البرامج".

النمط المحسوب
الشكل 3: سلسلة المهام الرئيسية التي تحلِّل CSS لإضافة أسلوب محسوب

حتى إذا لم تقدِّم أيّ ملف CSS، تحتوي كلّ عقدة DOM على أسلوب محسوب. يتم عرض علامة <h1> أكبر من علامة <h2> ويتم تحديد الهوامش لكل عنصر. ويرجع ذلك إلى أنّ المتصفّح يحتوي على جدول تنسيق تلقائي. إذا كنت تريد معرفة شكل ملف CSS التلقائي في Chrome، يمكنك الاطّلاع على رمز المصدر هنا.

التنسيق

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

لعبة أجهزة الفاكس
الشكل 4: شخص يقف أمام لوحة، وخط هاتف متصل بالشخص الآخر

التنسيق هو عملية للعثور على الشكل الهندسي للعناصر. ينتقل الخيط الرئيسي عبر DOM و الأنماط المحسوبة وينشئ شجرة التنسيق التي تحتوي على معلومات مثل إحداثيات x وy وحجم المربّع الحدودي. قد تكون شجرة التنسيق مشابهة من حيث البنية لشجرة نموذج كائن المستند (DOM)، ولكنها لا تحتوي إلا على معلومات متعلقة بما يظهر على الصفحة. في حال تطبيق display: none، لا يكون هذا العنصر جزءًا من شجرة التنسيق (ومع ذلك، يكون العنصر الذي يحتوي على visibility: hidden في شجرة التنسيق). وبالمثل، في حال تطبيق عنصر زائف يحتوي على محتوى مثل p::before{content:"Hi!"}، يتم تضمينه في شجرة التنسيق على الرغم من أنّه ليس في DOM.

التصميم
الشكل 5: سلسلة المهام الرئيسية التي تنتقل عبر شجرة نموذج DOM مع الأنماط المحسوبة وإنشاء شجرة التنسيق
الشكل 6: تنسيق المربّع للفقرة التي يتم نقلها بسبب تغيير فاصل السطر

إنّ تحديد تنسيق الصفحة هو مهمة صعبة. حتى أبسط تنسيق للصفحة، مثل تدفق محتوى ملف pdf من الأعلى إلى الأسفل، يجب أن يراعي حجم الخط ومكان فاصل الأسطر لأنّه يؤثر في حجم الفقرة وشكلها، ما يؤثر بدوره في موضع الفقرة التالية.

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

طلاء

لعبة رسم
الشكل 7: شخص أمام لوحة يحمل فرشاة طلاء ويتساءل عمّا إذا كان عليه رسم دائرة أولاً أو مربّع أولاً

لا يكفي توفُّر نموذج عناصر في المستند (DOM) وأسلوب وتنسيق لعرض الصفحة. لنفترض أنّك تحاول إعادة إنتاج لوحة. أنت تعرف حجم العناصر وشكلها وموقعها، ولكن عليك تحديد ترتيب رسمها.

على سبيل المثال، قد يتم ضبط z-index لعناصر معيّنة، وفي هذه الحالة سيؤدي الرسم بترتيب العناصر المكتوبة في HTML إلى عرض غير صحيح.

خطأ في z-index
الشكل 8: عناصر الصفحة التي تظهر بترتيب ترميز HTML، ما يؤدي إلى ظهور صورة معروضة بشكل خاطئ بسبب عدم مراعاة "فهرس z"

في خطوة الرسم هذه، تنتقل سلسلة التعليمات الرئيسية في شجرة التنسيق لإنشاء سجلات الرسم. سجلّ الطلاء هو ملاحظة عن عملية الطلاء، مثل "الخلفية أولاً، ثم النص، ثم المستطيل". إذا كنت قد رسمت على عنصر <canvas> باستخدام JavaScript، قد تكون هذه العملية مألوفة لك.

سجلّات الطلاء
الشكل 9: سلسلة المحادثات الرئيسية التي تنتقل عبر شجرة التنسيق وتُنشئ سجلات الطلاء

تحديث مسار العرض يتطلّب تكلفة عالية

الشكل 10: شجرة نموذج DOM+Style وLayout وPaint بترتيب إنشائها

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

إذا كنت تضيف تأثيرات متحركة إلى العناصر، على المتصفّح تنفيذ هذه العمليات بين كل إطار. تعمل معظم شاشاتنا على إعادة عرض المحتوى 60 مرة في الثانية (60 لقطة في الثانية)، ما يجعل الصور المتحركة تبدو سلسة أمام عيون البشر عند تحريك العناصر على الشاشة في كل لقطة. في المقابل، إذا لم يعرض المؤثر المتحرك الإطارات بين اللقطات، ستبدو الصفحة "مضطربة".

لقطات متقطعة بسبب عدم توفّر لقطات
الشكل 11: لقطات الصورة المتحركة على مخطط زمني

حتى إذا كانت عمليات العرض تتماشى مع معدل تحديث الشاشة، يتم تنفيذ هذه العمليات الحسابية في سلسلة المحادثات الرئيسية، ما يعني أنّه يمكن حظرها عندما يشغّل تطبيقك JavaScript.

jage jank by JavaScript
الشكل 12: لقطات متحركة على مخطط زمني، ولكن تم حظر لقطة واحدة بواسطة JavaScript

يمكنك تقسيم عملية JavaScript إلى أجزاء صغيرة وتحديد موعد لتشغيلها في كل إطار باستخدام requestAnimationFrame(). لمزيد من المعلومات حول هذا الموضوع، يُرجى الاطّلاع على مقالة تحسين تنفيذ JavaScript. يمكنك أيضًا تشغيل JavaScript في Web Workers لتجنُّب حظر سلسلة التعليمات الرئيسية.

طلب إطار صورة متحركة
الشكل 13: أجزاء أصغر من JavaScript يتم تشغيلها على مخطط زمني مع إطار للحركة

الدمج

كيف يمكنك رسم صفحة؟

الشكل 14: صورة متحركة لعملية التحويل إلى شبكة أساسية

الآن بعد أن عرف المتصفّح بنية المستند وأسلوب كل عنصر وشكل الصفحة وترتيب الرسم، كيف يرسم الصفحة؟ يُطلق على عملية تحويل هذه المعلومات إلى بكسل على الشاشة اسم "التحويل إلى شبكة بكسل".

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

ما المقصود بالتركيب؟

الشكل 15: صورة متحركة لعملية الدمج

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

يمكنك الاطّلاع على كيفية تقسيم موقعك الإلكتروني إلى طبقات في أدوات مطوّري البرامج باستخدام لوحة "الطبقات".

التقسيم إلى طبقات

لمعرفة العناصر التي يجب أن تكون في الطبقات التي يجب أن تكون فيها، ينتقل الخيط الرئيسي عبر شجرة التنسيق لإنشاء شجرة الطبقات (يُسمى هذا الجزء "تعديل شجرة الطبقات" في لوحة DevTools للأداء). إذا كانت أجزاء معيّنة من الصفحة التي يجب أن تكون طبقة منفصلة (مثل القائمة الجانبية التي تظهر من خلال التمرير) لا تحصل على طبقة، يمكنك التلميح للمتصفّح باستخدام سمة will-change في CSS.

شجرة الطبقات
الشكل 16: سلسلة المحادثات الرئيسية التي تنتقل عبر شجرة التنسيق لإنشاء شجرة الطبقات

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

تحويل الرموز النقطية والصور المركبة خارج سلسلة التعليمات الرئيسية

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

صورة نقطية
الشكل 17: سلاسل مهام معالجة الصور النقطية التي تنشئ الصورة النقطية للشرائح وترسلها إلى وحدة معالجة الرسومات

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

بعد تحويل المربّعات إلى وحدات بكسل، يجمع خيط المُركِّب معلومات المربّعات المسماة أربَع أضلاع للرسم لإنشاء إطار مُركِّب.

رسم مربّعات يحتوي على معلومات، مثل موقع المربّع في الذاكرة ومكان رسمه في الصفحة، مع مراعاة تركيب الصفحة.
إطار المكوّن مجموعة من الأشكال الرباعية التي تم إنشاؤها لتمثيل إطار صفحة

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

composit
الشكل 18: سلسلة مكوّن ينشئ إطارًا مركبًا يتم إرسال اللقطة إلى عملية المتصفّح ثم إلى وحدة معالجة الرسومات

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

الخاتمة

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

في المقالة التالية والأخيرة من هذه السلسلة، سنلقي نظرة على سلسلة المكوّن المرئي بمزيد من التفاصيل، وسنطّلع على ما يحدث عند إدخال المستخدم لعناصر مثل mouse move وclick.

هل أعجبك المنشور؟ إذا كانت لديك أي أسئلة أو اقتراحات بشأن مشاركة مستقبلية، يُسعدنا معرفة رأيك في قسم التعليقات أدناه أو على ‎@kosamari على Twitter.

الخطوة التالية: يتم نقل الإدخال إلى أداة الدمج