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