نموذج الطبقات
مقدمة
بالنسبة إلى معظم مطوّري الويب، فإنّ نموذج صفحة الويب الأساسي هو نموذج DOM. العرض هو عملية غير واضحة في أغلب الأحيان لتحويل هذا التمثيل للصفحة إلى صورة على الشاشة. غيّرت المتصفّحات الحديثة طريقة عمل العرض في السنوات الأخيرة للاستفادة من بطاقات الرسومات: غالبًا ما يُشار إلى ذلك بشكل غامض باسم "التسريع بالأجهزة". عند الحديث عن صفحة ويب عادية (أي ليست Canvas2D أو WebGL)، ما هو المقصود بهذه العبارة فعليًا؟ توضّح هذه المقالة النموذج الأساسي الذي يستند إليه العرض المُسرَّع بالأجهزة لمحتوى الويب في Chrome.
محاذير كبيرة وخطيرة
نتحدث هنا عن WebKit، وبشكل أكثر تحديدًا عن إصدار Chromium من WebKit. تتناول هذه المقالة تفاصيل تنفيذ Chrome، وليس ميزات النظام الأساسي للويب. لا تُدرِج منصة الويب والمعايير هذا المستوى من تفاصيل التنفيذ، لذا لا يمكن ضمان أن ينطبق أيّ شيء في هذه المقالة على المتصفّحات الأخرى، ولكن يمكن أن تكون معرفة العناصر الداخلية مفيدة في تصحيح الأخطاء المتقدّم وتحسين الأداء.
يُرجى العلم أيضًا أنّ هذه المقالة بأكملها تتناول جزءًا أساسيًا من بنية عرض Chrome التي تتغيّر بسرعة كبيرة. تحاول هذه المقالة تغطية العناصر التي يُرجّح ألا تتغيّر، ولكن لا يمكننا ضمان استمرار تطبيقها بعد ستة أشهر.
من المهم معرفة أنّ متصفّح Chrome يتضمّن منذ فترة مسارَين مختلفَين للعرض: مسار المعالجة المُسرَّعة بالأجهزة ومسار البرامج الأقدم. اعتبارًا من وقت كتابة هذه المقالة، يتم عرض جميع الصفحات باستخدام مسار سرعة الأجهزة على نظام التشغيل Windows وChromeOS وChrome لأجهزة Android. على أجهزة Mac وLinux، لا يتم استخدام المسار السريع إلا للصفحات التي تحتاج إلى دمج بعض محتوى الصفحة (اطّلِع أدناه على مزيد من المعلومات حول المحتوى الذي يتطلّب الدمج)، ولكن سيتم قريبًا استخدام المسار السريع لجميع الصفحات على هذه الأجهزة أيضًا.
أخيرًا، نلقي نظرة على محرك العرض وندرس ميزاته التي لها تأثير كبير في الأداء. عند محاولة تحسين أداء موقعك الإلكتروني، قد يكون من المفيد فهم نموذج الطبقات، ولكن من السهل أيضًا أن تضرّ نفسك: الطبقات هي بنى مفيدة، ولكن إنشاء الكثير منها يمكن أن يؤدي إلى زيادة النفقات العامة في حِزمة الرسومات. ننصحك بالتأكّد من ذلك.
من نموذج DOM إلى الشاشة
لمحة عن ميزة "الطبقات"
بعد تحميل الصفحة وتحليلها، يتم تمثيلها في المتصفّح كبنية مألوفة لدى العديد من مطوّري الويب: نموذج كائن المستند (DOM). ومع ذلك، عند عرض صفحة، يعرض المتصفّح سلسلة من العروض الوسيطة التي لا تظهر للمطوّرين مباشرةً. وأكثر هذه الهياكل أهمية هي الطبقة.
في Chrome، هناك في الواقع عدة أنواع مختلفة من الطبقات: طبقات التقديم (RenderLayers)، وهي مسؤولة عن الأشجار الفرعية لنموذج DOM، وطبقات الرسومات (GraphicsLayers)، وهي مسؤولة عن الأشجار الفرعية لطبقات التقديم. ونحن نهتم كثيرًا بالأخير، لأنّ GraphicsLayers هي التي يتم تحميلها إلى وحدة معالجة الرسومات كمواد تمويه. سأستخدم كلمة "الطبقة" من الآن فصاعدًا للإشارة إلى GraphicsLayer.
لمحة سريعة عن المصطلحات المتعلّقة بوحدة معالجة الرسومات: ما هو نسيج الصورة؟ يمكنك اعتبارها صورة نقطية تم نقلها من الذاكرة الرئيسية (أي ذاكرة الوصول العشوائي) إلى ذاكرة الفيديو (أي ذاكرة الفيديو الرام على وحدة معالجة الرسومات). بعد نقله إلى وحدة معالجة الرسومات، يمكنك ربطه بهندسة شبكة. في ألعاب الفيديو أو برامج التصميم بمساعدة الكمبيوتر (CAD)، تُستخدَم هذه التقنية لمنح النماذج الثلاثية الأبعاد الهيكلية "جلدًا". ويستخدم Chrome مواد النسيج للحصول على أجزاء من محتوى صفحات الويب على وحدة معالجة الرسومات. يمكن ربط الأنسجة بتكلفة منخفضة بمواضع وعمليات تحويل مختلفة من خلال تطبيقها على شبكة مستطيلة بسيطة جدًا. هذه هي طريقة عمل CSS الثلاثي الأبعاد، وهي رائعة أيضًا للانتقال السريع للأعلى أو للأسفل، ولكن سنتناول المزيد من التفاصيل حول كلتا الميزتين لاحقًا.
لنلقِ نظرة على بعض الأمثلة لتوضيح مفهوم الطبقات.
من الأدوات المفيدة جدًا عند دراسة الطبقات في Chrome علامة "عرض حدود الطبقات المركبة" في الإعدادات (أي رمز الترس الصغير) في "أدوات المطوّرين"، ضمن العنوان "العرض". تعمل هذه الميزة ببساطة على إبراز مواضع الطبقات على الشاشة. لنفعّل هذه الميزة. تم الحصول على جميع لقطات الشاشة والأمثلة هذه من أحدث إصدار من Chrome Canary، وهو الإصدار 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>

من خلال وضع خاصية CSS ثلاثية الأبعاد على الرمز <div>
الذي يُديره، يمكننا الاطّلاع على شكله عندما يحصل العنصر على طبقته الخاصة: يُرجى ملاحظة الحدود البرتقالية التي تُحدّد طبقة في هذا العرض.
معايير إنشاء الطبقات
ما هي العناصر الأخرى التي تحصل على طبقة خاصة بها؟ لقد تطورت الأساليب الاستقرائية في Chrome بمرور الوقت ولا تزال تتطوّر، ولكن في الوقت الحالي، يتم إنشاء أي من طبقات التنشيط التالية:
- سمات CSS للتحويل الثلاثي الأبعاد أو منظوري
- عناصر
<video>
التي تستخدم ميزة "فك ترميز الفيديو المسرَّع" <canvas>
عناصر ذات سياق ثلاثي الأبعاد (WebGL) أو سياق مُسرَّع ثنائي الأبعاد- المكوّنات الإضافية المركبة (مثل Flash)
- العناصر التي تتضمّن حركة CSS لشفافيتها أو تستخدم عملية تحويل متحركة
- العناصر التي تتضمّن فلاتر CSS مُسرَّعة
- يحتوي العنصر على عنصر فرعي له طبقة تركيب (بمعنى آخر، إذا كان العنصر يحتوي على عنصر فرعي في طبقته الخاصة)
- يحتوي العنصر على عنصر شقيق له قيمة z-index أقلّ ويتضمّن طبقة مركبة (بمعنى آخر، يتم عرض العنصر فوق طبقة مركبة).
الآثار العملية: الصور المتحركة
يمكننا أيضًا نقل الطبقات، ما يجعلها مفيدة جدًا للصور المتحركة.
الشكل 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، وإذا كان الطلاء طويلاً، سيؤدي ذلك إلى حدوث مشاكل أو تأخيرات في الرسوم المتحرّكة.
اطّلِع على سبيل المثال على طريقة العرض هذه للمخطط الزمني في "أدوات المطوّرين": لا تتوفّر أي عمليات رسم أثناء دوران هذه الطبقة ذهابًا وإيابًا.

غير صالح إعادة الطلاء
ولكن إذا تغيّر محتوى الطبقة، يجب إعادة رسمها.
الشكل 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>
في كل مرة يتم فيها النقر على عنصر الإدخال، يزداد عرض العنصر المتغيّر بمقدار بكسل واحد. يؤدي ذلك إلى إعادة ترتيب العنصر بالكامل وإعادة رسمه، وهو في هذه الحالة طبقة كاملة.
من الطرق الجيدة لمعرفة ما يتمّ رسمه هي استخدام أداة "إظهار مستطيلات الطلاء" في "أدوات المطوّر"، ضمن عنوان "العرض" في إعدادات "أدوات المطوّر" أيضًا. بعد تفعيله، لاحظ أنّ العنصر المتحرك والزر يضيئان باللون الأحمر عند النقر على الزر.

تظهر أحداث الرسم أيضًا في المخطط الزمني لأداة المطوّرين. قد يلاحظ القرّاء الملاحظون أنّ هناك حدثَي رسم: أحدهما للطبقة والآخر للزر نفسه، والذي تتم إعادة رسمه عند تغييره إلى/من حالته المُضغوطة.

يُرجى العِلم أنّ Chrome لا يحتاج دائمًا إلى إعادة رسم الطبقة بأكملها، بل يحاول إعادة رسم جزء نموذج DOM الذي تم إلغاء صلاحيته فقط. في هذه الحالة، عنصر DOM الذي عدّلناه هو حجم الطبقة بأكملها. ولكن في العديد من الحالات الأخرى، سيكون هناك الكثير من عناصر DOM في طبقة.
السؤال التالي الواضح هو ما الذي يتسبب في إلغاء القيمة وفرض إعادة الطلاء. من الصعب الإجابة عن هذا السؤال بشكل شامل لأنّ هناك الكثير من الحالات الشاذة التي يمكن أن تؤدي إلى إلغاء القيمة. إنّ السبب الأكثر شيوعًا هو تلويث DOM من خلال التلاعب بأنماط CSS أو التسبب في إعادة التصميم. نشر "توني جنتيلكور" مقالة مدوّنة رائعة عن أسباب إعادة التنسيق، ونشر "ستويان ستيفانوف" مقالة تتناول عملية الرسم بمزيد من التفصيل (ولكنّها تنتهي بعملية الرسم فقط، وليس بعمليات الدمج المميّزة).
إنّ أفضل طريقة لمعرفة ما إذا كان ذلك يؤثر في العنصر الذي تعمل عليه هي استخدام أدات "مخطّط زمني" في "أدوات المطوّر" وأداة "عرض مستطيلات الطلاء" لمعرفة ما إذا كنت تعيد الطلاء عندما لا تريد ذلك، ثم محاولة تحديد مكان تلويث DOM مباشرةً قبل إعادة التنسيق أو إعادة الطلاء. إذا كان لا بد من الرسم ولكن يبدو أنّه يستغرق وقتًا طويلاً بشكل غير معقول، اطّلِع على مقالة Eberhard Gräther حول وضع الرسم المستمر في "أدوات المطوّرين".
تجميع العناصر: نموذج DOM إلى الشاشة
إذًا، كيف يحوّل Chrome نموذج DOM إلى صورة شاشة؟ من الناحية المفاهيمية، تشمل هذه الميزة ما يلي:
- تأخذ نموذج DOM وتقسمه إلى طبقات
- ترسم كل طبقة من هذه الطبقات بشكل مستقل في ملفات رسومات نقطية للبرامج
- تحميلها إلى وحدة معالجة الرسومات كمواد عرض
- تجميع الطبقات المختلفة معًا في صورة الشاشة النهائية
يجب أن يحدث كل ذلك في المرة الأولى التي يُنشئ فيها Chrome إطارًا لصفحة ويب. بعد ذلك، يمكن أن تأخذ بعض الاختصارات للإطارات المستقبلية:
- في حال تغيير خصائص معيّنة من CSS، ليس من الضروري إعادة طلاء أيّ شيء. يمكن لمتصفّح Chrome إعادة دمج الطبقات الحالية التي تم عرضها على وحدة معالجة الرسومات كصور، ولكن باستخدام خصائص دمج مختلفة (مثلاً في مواضع مختلفة وبدرجات مختلفة من الشفافية وما إلى ذلك).
- إذا تم إلغاء جزء من طبقة، تتم إعادة رسمه وإعادة تحميله. إذا ظل المحتوى كما هو ولكن تغيّرت السمات المجمّعة (مثلاً، تم ترجمته أو تغيّر مستوى الشفافية)، يمكن أن يترك Chrome المحتوى على وحدة معالجة الرسومات ويعيد دمجه لإنشاء إطار جديد.
كما يتضح الآن، فإنّ نموذج الدمج المستنِد إلى الطبقات له تأثيرات عميقة في أداء العرض. تكون عملية الدمج سريعة نسبيًا عندما لا يكون هناك حاجة إلى طلاء أي شيء، لذا فإنّ تجنُّب إعادة طلاء الطبقات هو هدف جيد بشكل عام عند محاولة تصحيح أخطاء أداء العرض. سيلقي المطوّرون الخبراء نظرة على قائمة عوامل تشغيل الدمج أعلاه وسيدركون أنّه من الممكن فرض إنشاء الطبقات بسهولة. ولكن احرِص على عدم إنشائها بشكل عشوائي، لأنّها ليست مجانية: فهي تستهلك ذاكرة الوصول العشوائي للنظام ووحدة معالجة الرسومات (وخاصةً على الأجهزة الجوّالة)، ويمكن أن يؤدي استخدام الكثير منها إلى زيادة أخرى في المنطق الذي يتتبّع العناصر المرئية. يمكن أن تؤدي العديد من الطبقات أيضًا إلى زيادة الوقت الذي تستغرقه عملية التحويل إلى صيغة نقطية إذا كانت الطبقات كبيرة وتتداخل كثيرًا في أماكن لم تكن تتداخل فيها سابقًا، ما يؤدي إلى ما يُشار إليه أحيانًا باسم "الرسم الزائد". لذا، استخدِم معرفتك بحكمة.
هذا كلّ شيء في الوقت الحالي. يُرجى متابعتنا للحصول على المزيد من المقالات حول الآثار العملية لنموذج الطبقات.