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

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>

רוצים לנסות?

ה-<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 בסדר הבא. כך אפשר להציג את התוכן במסך מהר ככל האפשר, וגם לקצר את משך הזמן בין עדכוני המסך אחרי העיבוד הראשוני. כלומר, אפשר להשיג קצב רענון גבוה יותר של תוכן אינטראקטיבי.

משוב