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

Ilya Grigorik
Ilya Grigorik

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

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

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

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

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

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

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

  1. החל מהרמה הבסיסית (root) של עץ ה-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>

רוצים לנסות?

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

מתבצע חישוב של פרטי הפריסה

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

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

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

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

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

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

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

דף Hello World שעבר רינדור

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

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

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

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

משוב