תאריך פרסום: 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 פשוט עם טקסט ותמונה אחת. איך הדפדפן מעבד את הדף הזה?
- המרה: הדפדפן קורא את הבייטים הגולמיים של HTML מהדיסק, או מתרגמת אותם לתווים ספציפיים בהתאם קידוד הקובץ (לדוגמה, UTF-8).
- יצירת אסימונים: הדפדפן ממיר מחרוזות תווים לייחודיות
אסימונים – כפי שמצוין בתקן W3C HTML5
לדוגמה,
<html>
,<body>
— ומחרוזות אחרות בתוך בסוגריים זוויתיים. לכל אסימון יש משמעות מיוחדת וקבוצת כללים משלו. - ניתוח תחבירי: האסימונים שנפלטים מומרים ל'אובייקטים' שמגדירים את המאפיינים והכללים שלהם.
- יצירת DOM: לבסוף, מאחר שסימון ה-HTML מגדיר קשרים בין תגים שונים (חלק מהתגים נכללים בתגים אחרים), האובייקטים שנוצרים מקושרים במבנה נתונים של עץ, שמתעד גם את יחסי ההורה-צאצא שהוגדרו בסימון המקורי: האובייקט HTML הוא הורה של האובייקט body, האובייקט body הוא הורה של האובייקט paragraph, וכן הלאה, עד שנוצרת ההצגה המלאה של המסמך.
הפלט הסופי של התהליך כולו הוא מודל אובייקטי המסמך (DOM) של הדף הפשוט, שבו הדפדפן משתמש לכל עיבוד נוסף של .
בכל פעם שהדפדפן מעבד סימון HTML, הוא עובר את כל השלבים שהוגדרו קודם: המרת בייטים לתווים, זיהוי אסימונים, המרת אסימונים לצמתים וליצור של עץ DOM. כל התהליך הזה יכול להימשך לא מעט זמן, במיוחד אם יש לנו כמות גדולה של HTML לעיבוד.
אם פותחים את כלי הפיתוח ל-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:
הבייטים של ה-CSS מומרים לתווים, לאחר מכן לאסימונים, ואז לצמתים לבסוף, הם מקושרים למבנה עץ שנקרא 'מודל אובייקט CSS' (CSSOM):
למה ל-CSSOM יש מבנה עץ? כשמחשבים את הקבוצה הסופית של הסגנונות לכל אובייקט בדף, הדפדפן מתחיל עם הכלל הכללי ביותר שחלים על הצומת הזה (לדוגמה, אם הוא צאצא של רכיב גוף, כל סגנונות הגוף חלים עליו), ולאחר מכן משפר באופן רציף את הסגנונות המחושבים על ידי החלת כללים ספציפיים יותר. כלומר, הכללים 'יורדים במורד'.
כדי להמחיש את העניין, נתייחס לעץ ה-CSSOM שמתואר למעלה. לכל טקסט שמופיע בתג <span>
שממוקם ברכיב body יש גופן בגודל 16 פיקסלים והוא מודגש באדום – ההוראה font-size
מועברת בירושה מה-body
ל-span
. עם זאת, אם span
הוא צאצא של
בפסקה (p
), התוכן שלו לא מוצג.
כמו כן, חשוב לשים לב שהעץ שתואר קודם לכן הוא לא עץ ה-CSSOM המלא. מציג רק את הסגנונות שהחלטנו לשנות בגיליון הסגנונות שלנו. כל דפדפן מספק קבוצת סגנונות ברירת מחדל שנקראת גם 'סגנונות של סוכן משתמש'. אלה הסגנונות שאנחנו רואים כשאנחנו לא מספקים סגנונות משלו. הסגנונות שלנו מבטלים את ברירת המחדל הזו.
כדי לבדוק כמה זמן נמשכת עיבוד ה-CSS, אפשר לתעד ציר זמן ב-DevTools ולחפש את האירוע 'חישוב מחדש של סגנון': בניגוד לניתוח DOM, בציר הזמן לא מוצגת רשומה נפרדת של 'ניתוח CSS', אלא במקום זאת מתועדים הניתוח והבנייה של עץ CSSOM, וגם החישוב הרקורסיבי של סגנונות מחושבים באירוע אחד.
עיבוד הסגנונות הטריוויאליים שלנו נמשך כ-0.6 אלפיות השנייה ומשפיע על שמונה רכיבים הדף — לא הרבה, אבל שוב, לא בחינם. אבל איפה מהם מגיעים שמונה אלמנטים? ה-CSSOM וה-DOM הם מבני נתונים עצמאיים! מסתבר שהדפדפן מסתיר שלב חשוב. בשלב הבא, render עץ יוצרת קישור בין ה-DOM וה-CSSOM.