בניית מודל האובייקטים

Ilya Grigorik
Ilya Grigorik

תאריך פרסום: 31 במרץ 2014

כדי שהדפדפן יוכל ליצור את הדף, הוא צריך ליצור את עצי ה-DOM ו-CSSOM. לכן, אנחנו צריכים לוודא שאנחנו מעבירים את ה-HTML ואת ה-CSS לדפדפן מהר ככל האפשר.

סיכום

  • בייטים → תווים → אסימונים → צמתים → מודל אובייקטים.
  • הרכיבים של ה-HTML עוברים טרנספורמציה ל-Document Object Model ‏ (DOM), והרכיבים של ה-CSS עוברים טרנספורמציה ל-CSS Object Model ‏ (CSSOM).
  • DOM ו-CSSOM הם מבני נתונים עצמאיים.
  • חלונית הביצועים של כלי הפיתוח של Chrome מאפשרת לנו לתעד ולבדוק את עלויות היצירה והעיבוד של DOM ו-CSSOM.

Document Object Model‏ (DOM)

<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="width=device-width,initial-scale=1" />
    <link href="style.css" rel="stylesheet" />
    <title>Critical Path</title>
  </head>
  <body>
    <p>Hello <span>web performance</span> students!</p>
    <div><img src="awesome-photo.jpg" /></div>
  </body>
</html>

רוצים לנסות?

מתחילים מהמקרה הפשוט ביותר: דף HTML פשוט עם טקסט ותמונה אחת. איך הדפדפן מעבד את הדף הזה?

תהליך היצירה של DOM

  1. המרה: הדפדפן קורא את הבייטים הגולמיים של ה-HTML מהדיסק או מהרשת ומתרגם אותם לתווים נפרדים על סמך הקידוד שצוין של הקובץ (לדוגמה, UTF-8).
  2. יצירת אסימונים: הדפדפן ממיר מחרוזות של תווים לאסימונים נפרדים, כפי שמפורט בתקן W3C HTML5, למשל <html>,‏ <body>, ומחרוזות אחרות בתוך סוגריים משולשים. לכל אסימון יש משמעות מיוחדת וקבוצת כללים משלו.
  3. ניתוח תחבירי: האסימונים שנוצרים מומרים ל'אובייקטים' שמגדירים את המאפיינים והכללים שלהם.
  4. יצירת DOM: לבסוף, מאחר שסימון ה-HTML מגדיר קשרים בין תגים שונים (חלק מהתגים נכללים בתגים אחרים), האובייקטים שנוצרים מקושרים במבנה נתונים של עץ, שמתעד גם את יחסי ההורה-צאצא שהוגדרו בסימון המקורי: האובייקט HTML הוא הורה של האובייקט body, האובייקט body הוא הורה של האובייקט paragraph, וכן הלאה, עד שנוצר הייצוג המלא של המסמך.

עץ DOM

הפלט הסופי של התהליך כולו הוא מודל אובייקט המסמך (DOM) של הדף הפשוט שלנו, שבו הדפדפן משתמש לכל העיבוד הנוסף של הדף.

בכל פעם שהדפדפן מעבד סימון HTML, הוא עובר את כל השלבים שהוגדרו קודם: המרת בייטים לתווים, זיהוי אסימונים, המרת אסימונים לצמתים וליצור של עץ ה-DOM. התהליך כולו עשוי להימשך זמן מה, במיוחד אם יש לנו כמות גדולה של HTML לעיבוד.

מעקב אחר יצירת DOM ב-DevTools

אם פותחים את כלי הפיתוח ל-Chrome ומתעדים ציר זמן בזמן טעינת הדף, אפשר לראות את הזמן בפועל שנדרש לביצוע השלב הזה. בדוגמה הקודמת, נדרשו לנו כ-5 אלפיות השנייה כדי להמיר קטע של HTML לעץ DOM. בדפים גדולים יותר, התהליך עשוי להימשך הרבה יותר זמן. כשאתם יוצרים אנימציות חלקות, זה יכול להפוך לצווארון בקבוק אם הדפדפן צריך לעבד כמויות גדולות של HTML.

עץ ה-DOM מתעד את המאפיינים והיחסים של תגי העיצוב של המסמך, אבל הוא לא אומר לנו איך הרכיב ייראה אחרי העיבוד. זוהי האחריות של ה-CSSOM.

מודל אובייקטים של CSS‏ (CSSOM)

בזמן שהדפדפן יצר את ה-DOM של הדף הבסיסי שלנו, הוא נתקל ברכיב <link> ב-<head> של המסמך שמפנה לגיליון סגנונות CSS חיצוני: style.css. מאחר שהשרת צופה שהוא יצטרך את המשאב הזה כדי להציג את הדף, הוא שולח מיד בקשה למשאב הזה, שמתקבלת עם התוכן הבא:

body {
  font-size: 16px;
}

p {
  font-weight: bold;
}

span {
  color: red;
}

p span {
  display: none;
}

img {
  float: right;
}

יכולנו להצהיר על הסגנונות שלנו ישירות בתוך ה-HTML (inline), אבל שמירת ה-CSS בנפרד מה-HTML מאפשרת לנו להתייחס לתוכן ולעיצוב כנושאים נפרדים: מעצבים יכולים לעבוד על CSS, מפתחים יכולים להתמקד ב-HTML וגם בנושאים אחרים.

בדומה ל-HTML, אנחנו צריכים להמיר את כללי ה-CSS שהתקבלו למשהו שהדפדפן יכול להבין ולעבוד איתו. לכן, אנחנו חוזרים על התהליך של ה-HTML, אבל עבור CSS במקום HTML:

שלבי היצירה של CSSOM

הבייטים של ה-CSS מומרים לתוים, לאחר מכן לאסימונים, לאחר מכן לצמתים, ולבסוף הם מקושרים למבנה עץ שנקרא 'מודל אובייקטים של CSS' (CSSOM):

עץ CSSOM

למה ל-CSSOM יש מבנה עץ? כשמחשבים את הקבוצה הסופית של הסגנונות לכל אובייקט בדף, הדפדפן מתחיל עם הכלל הכללי ביותר שחלים על הצומת הזה (לדוגמה, אם הוא צאצא של רכיב גוף, אז כל סגנונות הגוף חלים עליו), ולאחר מכן משפר באופן רקורסיבי את הסגנונות המחושבים על ידי החלת כללים ספציפיים יותר. כלומר, הכללים 'יורדים במורד'.

כדי להמחיש את העניין, נתייחס לעץ ה-CSSOM שמתואר למעלה. לכל טקסט שמופיע בתג <span> שממוקם ברכיב body יש גופן בגודל 16 פיקסלים והוא מודגש באדום – ההוראה font-size מועברת במורד העץ מה-body ל-span. עם זאת, אם span הוא צאצא של תג של פסקה (p), התוכן שלו לא מוצג.

כמו כן, חשוב לזכור שהעץ שתואר קודם הוא לא עץ ה-CSSOM המלא, והוא מציג רק את הסגנונות שהחלטנו לשנות בגיליון הסגנונות שלנו. כל דפדפן מספק קבוצת סגנונות ברירת מחדל שנקראת גם 'סגנונות של סוכן משתמש'. אלה הסגנונות שאנחנו רואים כשאנחנו לא מספקים סגנונות משלו. הסגנונות שלנו מבטלים את ברירת המחדל הזו.

כדי לבדוק כמה זמן נמשכת עיבוד ה-CSS, אפשר לתעד ציר זמן ב-DevTools ולחפש את האירוע 'חישוב מחדש של סגנון': בניגוד לניתוח DOM, בציר הזמן לא מוצגת רשומה נפרדת של 'ניתוח CSS', ובמקום זאת מתועדים הניתוח והבנייה של עץ CSSOM, וגם החישוב הרקורסיבי של סגנונות מחושבים באירוע אחד.

מעקב אחר היצירה של CSSOM בכלי הפיתוח

עיבוד ה-sheet של הסגנונות הטריוויאליים שלנו נמשך כ-0.6 אלפיות השנייה, והוא משפיע על שמונה רכיבים בדף – לא הרבה, אבל שוב, לא בחינם. עם זאת, מאיפה הגיעו שמונה הרכיבים האלה? ‏CSSOM ו-DOM הם מבני נתונים עצמאיים! מסתבר שהדפדפן מסתיר שלב חשוב. בשלב הבא נסביר על עץ הרינדור שמקשר בין DOM ל-CSSOM.

משוב