בנייה, פריסה וצבע של עץ עיבוד

Ilya Grigorik
Ilya Grigorik

פורסם: 31 במרץ 2014

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

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

סיכום

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

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

ה-DOM וה-CSSOM משולבים כדי ליצור את עץ העיבוד.

כדי ליצור את עץ העיבוד, הדפדפן מבצע בערך את הפעולות הבאות:

  1. החל משורש עץ ה-DOM, עוברים על כל צומת גלוי.

    • חלק מהצמתים לא גלויים (למשל תגי סקריפט, תגי מטא וכו'), והם מושמטים כי הם לא משתקפים בפלט המעובד.
    • חלק מהצמתים מוסתרים באמצעות CSS ומוסרים גם מעץ העיבוד. לדוגמה, צומת ה-span – בדוגמה שלמעלה – חסר מעץ העיבוד כי יש לנו כלל מפורש שמגדיר את המאפיין display: none.
  2. לכל צומת גלוי, מוצאים את כללי ה-CSSOM התואמים ומחילים אותם.

  3. פליטת צמתים גלויים עם תוכן והסגנונות המחושבים שלהם.

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

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

כדי לגלות את הגודל והמיקום המדויקים של כל אובייקט בדף, הדפדפן מתחיל בשורש של עץ העיבוד ועובר דרכו. עיין בדוגמה זו:

<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="width=device-width,initial-scale=1" />
    <title>Critial Path: Hello world!</title>
  </head>
  <body>
    <div style="width: 50%">
      <div style="width: 50%">Hello world!</div>
    </div>
  </body>
</html>

כדאי לעיין בדוגמה הזו של HTML שעבר עיבוד כדף אינטרנט.

ה-<body> בדוגמה הקודמת מכיל שני רכיבי <div> מוטמעים: הראשון (הורה) <div> מגדיר את גודל התצוגה של הצומת ל-50% מרוחב אזור התצוגה, והשני <div> – שמוכל על ידי ההורה – מגדיר את ה-width שלו ל-50% מההורה שלו, כלומר 25% מרוחב אזור התצוגה.

חישוב מידע על הפריסה על סמך התיאור הקודם.

הפלט של תהליך פריסת הרכיבים הוא 'מודל תיבות', שמתעד במדויק את המיקום והגודל של כל רכיב באזור התצוגה: כל המידות היחסיות מומרות לפיקסלים מוחלטים במסך.

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

התהליך הזה יכול לקחת זמן כי הדפדפן צריך לבצע הרבה פעולות. עם זאת, כלי פיתוח ל-Chrome יכולים לספק תובנות לגבי כל שלושת השלבים שתוארו קודם. כדאי לבדוק את שלב הפריסה בדוגמה המקורית שלנו 'hello world':

מדידת פריסה בכלי הפיתוח.

  • האירוע Layout (פריסה) מתעד את בניית עץ העיבוד, המיקום וחישוב הגודל בציר הזמן.
  • בסיום הפריסה, הדפדפן מנפיק אירועים מסוג Paint Setup (הגדרת צביעה) ו-Paint (צביעה), שממירים את עץ העיבוד לפיקסלים במסך.

הזמן שנדרש לביצוע בנייה, פריסה וציור של עץ הרינדור משתנה בהתאם לגודל המסמך, לסגנונות שמוחלים עליו ולמכשיר שבו הוא פועל: ככל שהמסמך גדול יותר, כך הדפדפן צריך לעבוד יותר; ככל שהסגנונות מורכבים יותר, כך נדרש יותר זמן לציור (לדוגמה, ציור של צבע אחיד הוא "זול", בעוד שציור של צללית הוא "יקר" מבחינת חישוב ורינדור).

הדף גלוי סוף סוף באזור התצוגה:

דף מעובד עם הכיתוב 'שלום, סטודנטים לביצועים באינטרנט!' ועם מם של כלב חמוד שאומר לך שאתה מדהים.

סיכום קצר של השלבים בדפדפן:

  1. עיבוד תגי עיצוב HTML ויצירת עץ ה-DOM.
  2. מעבדים את תגי העיצוב של CSS ויוצרים את עץ ה-CSSOM.
  3. שילוב של DOM ו-CSSOM בעץ עיבוד.
  4. מריצים את הפריסה בעץ העיבוד כדי לחשב את הגיאומטריה של כל צומת.
  5. צובעים את הצמתים הבודדים במסך.

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

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