المقدمة

في المقال الي فات  والي ممكن تشوفه من هنا  اتكلمنا عن رحلة ال user من أول ما بيكتب اسم موقع أو يضغط علي رابط معين لحد ما ال browser بيستلم أول byte من السيرفر، وفي المقال دا هنتكلم عن إزاي المتصفح بيبدأ يفهم ال bytes اللي جايه من السيرفر لحد ما يحولها لموقع interactive متكامل يقدر يتفاعل معاه، ودا بيتم عن طريق بعض الخطوات تسمى ب ال Critical reading path .


Critical reading path

ال critical rendering path عبارة عن خطوات بيتبعها المتصفح علشان يحول ال bytes اللي بيستلمها من ال server ل pixels  بتظهر ل ال user علي الشاشة يقدر يتفاعل معاها،  والخطوات دي بتتمثل في الآتي .

  • Dom construction
  • Cssom construction
  • Rendering

Dom construction

أول ما المتصفح ما بيستلم أول جزء من البيانات من السيرفر واللي بتكون عبارة عن مجموعة bytes متمثلة في ملف ال HTML، بيبدأ  يحلل البيانات دي (يعملها parsing) ويوصل في النهايه ل Dom object model ودا بيتم عن طريق بعض الخطوات .

  1. التحويل من Bytes لـ Characters المتصفح بيقرأ الـ HTML كـ Bytes من ال Server وبيحوّلهم لحروف بناءً على نوع التشفير (زي UTF-8) مثلا .
  2. Tokenizing (التقطيع) المتصفح بيقسم الحروف دي لرموز بتسمي (tokens) زي <html>, <body>.
  3. Lexing (تحويل الرموز ل objects) الرموز دي بتتحوّل ل (Objects) بتوضح خصائصها وقواعدها وال attributes وال methods الي بتحتويها .
  4. بناء شجرة الـ DOM وربط العناصر ببعضها .اخيرا بيبدأ  المتصفح بيربط ال objects دي على شكل شجرة فيها علاقات "أب وابن" يعني <html> هو الأب الخاص ل ال <body> وهكذا .

Preload Scanner  

في الوقت الي بيكون في المتصفح بيبني ال DOM  بيكون ال Preload Scanner عمل  scan ل ملف HTML وبيعمل fetch لكل ال resource الموجود زي ملفات CSS أو JavaScript وال images أو الخطوط قبل ما ال browser يوصلها أثناء عملية ال parsing.

ليه ال Preload Scanner مهم ؟

لو المتصفح استنى لحد ما يوصل ل ال <img />أو  <script> أو <link> او أي يكن ال resource جوّه الصفحة عشان يطلبه، ده هيبطّأ تحميل الصفحة خصوصا في وجود عناصر ال Blocking Render Resource (عناصر وجودها أساسي للعرض الاول زي ال CSS)، لكن بفضل الـ Preload Scanner المتصفح بيقدر يطلب ال resources دي من بدري في الخلفية، فـ لما المتصفح يوصل للعنصر ده، ممكن يكون التحميل خلاص بدأ أو حتى خلص، وده بيقلل الوقت اللي ممكن الصفحة تتأخر فيه، ويخليها تشتغل أسرع.


Rendering blocking resources & Parsing blocking resources

أثناء عملية ال parsing المتصفح بيقابل بعض ال resources الي ممكن توقف عملية ال parsing وبالتبعية بتوقف عملية ال rendering زي مثلا ملفات ال JS (بشرط انه متكونش deferred)، وهنا بتتوقف عملية ال  parsing لحين تنفيذ ال script ، وتنفيذه بيتم كالتالي .

  1. تحليل الكود (Parsing): بيحوّل الكود ل tree تسمي ال  (AST) اختصار ل abstract syntax tree.
  2. تحويل ال AST ل بايت كود (Bytecode): بعد كده بتبدأ المتصفحات تاخد ال (AST) دي وتحوّلها لحاجة اسمها   bytecode علشان بعد كده يتعملها run علي ال main thread.
  3. تنفيذ ال bytecode: الكود بيبدأ يشتغل علي ال الـ main thread.
💡
ملحوظة : ال Css resource الي بيكون موجود في ال link تاج يعتبر Render Blocking Resource ودا معناه انه بيوقف عملية ال Rendering (واحده من مهام ال Rendering رسم آل DOM علي علي الشاشة) لكنه لا يعوق عملية ال Parsing

  CSSOM Construction

بعد ما المتصفح بني ال DOM Tree بيجي الدور علي ال CSSOM الي من خلالها المتصفح بيعرف لون، وحجم، ونوع الخط ومكان كل عنصر في في الصفحة، وخطوات انشاء ال CSSOM نفسها نفس ال DOM عن طريق قراءت ال Bytes وتحولها الي حروف ومنها الي Tokens ومنها الي CSSOM  نفسها .

كيفية اختيار ال CSS Properties  للعنصر ؟ 

بيبدأ المتصفح يطبق القواعد الخاصة بيه لكل عنصر (user agent stylesheet) ودي بتختلف من متصفح للتاني وتعبر ال styles ال default لاي عنصر،ويعدها المتصفح بيقرأ ملفات ال CSS ويبدأ كل عنصر يورث الخصائص الخاصه بيه للعناصر الي جواه .

💡
ملحوظة : مش كل ال css properties يمكن توريثها من ال parent الي ال child لكن دا بيعتمد علي ال property نفسها هل هي inherited ولا لأ وممكن نشيك علي دا من خلال ال موقع ال MDN

طيب بيجي سؤال مهم هنا وهو لو عندي أكثر من خاصية ل ال CSS لنفس ال component مين فيهم هيطبق ؟ وهنا يجي دور  ال CSS Cascading، ودي عبارة عن 3 قواعد اللي من خلالها بيعرف المتصفح يطبق انهي style .

  1. Specificity 
  2. Sort Order
  3. Important key word

اولا ال specificity او  (الأولوية) ودا عبارة عن نظام بيدي كل selector رقم بيعبر عن مدي قوته زي ماهو موضح في الجدول التالي .

النوع النقاط
Inline style 1000
ID 100
Class أو attribute أو pseudo 10
اسم التاج زي div أو p 1

تاني شئ وهو ال  Order وبيتم اللجوء له في حالة تساوي ال Specificity لنفس ال selector

وثالث وآخر شئ وهو ال important key ودا بيكون مطبق علي مستوي ال style property نفسه مش ال selecort (زي مثلا color:red !important ) وبيكون اقوي من اي selector، وفي حالة وجود اكثر من important key بيتم الرجوع لقواعد ال specificity وال source order مرة تاني .

مثال:

div { // 1 point
  color: blue;
}
#header { // 100 points
  color: green;
}
#header .title { // 110 points (this will be applied)
  color: red;
}


Building the Accessibility Tree

الخطوة دي مهمة جدًا، خاصة لذوي الاحتياجات الخاصة، بيبدأ المتصفح يبني يبني شجرة تانية اسمها accessibility tree، ودي تعتبر نسخة مبسطة ومفهومة من الصفحة علشان أدوات المساعدة زي ال screen readers تقدر تتعامل الموقع، وكمان الشجرة دي بتتحدث تلقائيًا في كل ما يحصل فيها أي تغيير في الـ DOM .


Rendering

ثالث وآخر خطوة وهي خطوة ال Rendering  اللي من خلالها بيحول بيها المتصفح ال DOM وال CSSOM لصفحة حقيقية بتتشاف على الشاشة من خلال 4 خطوات أساسية .

  1. الـ Building Rendering Tree
    المتصفح بيدمج الـ DOM و CSSOM (اللي اتعملوا في الخطوات اللي فاتت) ويبدأ يطبّق كل الستايلات على العناصر، يعني يحدد كل عنصر لونه، حجمه، نوع الخط … الخ، كمان ال browser بعمل skip للعناصر الي مش بتبقي ظاهرة في الشاشة زي ال head وال meta tag والعناصر المخفيه الي بتكون واخده display يساوي none.
  2. الـ Layout (أو Reflow)
    بعد ما عرف الستايل، يبدأ يحدد مكان كل عنصر في الصفحة (إحداثياته – فوق، تحت، يمين، شمال).
  3. الـ Paint
    دلوقتي بقى يقدر يرسم العناصر على الشاشة، كل عنصر (سواء نص، صورة، خلفية... إلخ) بيترسم على حسب الستايل المُطبق عليها من الخطوة الأولي، وفي بعض الحالات المتصفح ممكن يرسم عناصر معينة في طبقات منفصلة والطبقات دي بتترسم على الـ GPU بدل CPU، وده بيسرّع الأداء وبيقلل الضغط على الـ main thread، فبيخلي الصفحة أسرع وأكتر سلاسة، الحالات دي ممكن تكون مثلا عناصر أو خصائص CSS معينة بتخلي المتصفح يعمل Layer تلقائيًا، زي: <canvas> أو <video> او خصائص css زي ال opacity او will-change أو transform أو opacity;
  4. الـ Compositing 

لما المتصفح يرسم الصفحة، بيقسّمها لـ طبقات (Layers) علشان يعرف يحط عناصر فوق بعضها،  يعني لو في عنصر لازم يبقى قدّام عنصر تاني بسبب ال z-index وال stacking context بيبدأ ال browser يحط كل عنصر في الطبقة المناسبة ليه .


التفاعل مع الصفحة (Interactivity)

لما الصفحة تخلص تحميل وتترسم على الشاشة، ممكن تفتكر إن كده كله تمام! بس الحقيقة مش دايمًا كده، احيانا بيكون عندنا JavaScript كان مؤجل (deferred) زي ما ذكرنا قبل كدا ال <"script defer src="path/> ،او script بيشتغل بعد ما حدث الـ onload ما يخلص، وال js دا بيكون شغال علي ال  الـ main thread  وبيفضل مشغول لحد ما ال execution م يخلص وساعتها المستخدم مش بيقدر يتفاعل مع الصفحة كويس زي مثلا انه يعمل scroll، أو يضغط على زرار، أو يكتب في ال input field لأن الـ  main thread  مشغول بتنفيذ ال js وهنا بيجي مصطلح مهم اسمه ال Time to Interactive  واختصارة (TTI) ودا الوقت الي بياخده المتصفح من بدايه ال user يضغط علي ال link الموقع لحد ما المتصفح يكون interactive .


في الختام

في المقال دا اتكلمنا علي الخطوات الي بيمر بيها المتصفح علشان يعرض صفحة الويب من أول ما بيستلم ال bytes من ال server لحد ما صفحة الويب تكون ظاهرة ل ال user بشكل تفاعلي والي اللقاء في مقال اخر ودمتم سالمين.