זמני צבע CSS ומשקל עיבוד הדף

Colt McAnlis
Colt McAnlis

מבוא

אם אתם מהאנשים שמתעניינים בנושאים כמו איך דפדפנים פועלים, אתם כבר יודעים שלאחרונה פורסמו כמה מאמרים מדהימים שמפרטים את פעולת הרינדור/הקומפוזיציה המואצת של ה-GPU ב-Chrome. קודם כול, המאמר Accelerated Rendering in Chrome: The Layer Model (עיבוד מואץ ב-Chrome: מודל השכבות) הוא מבוא מצוין לאופן שבו Chrome משתמש בקונספט של שכבות כדי לצייר את הדף. במאמר GPU Accelerated Compositing in Chrome (הרכבה מואצת של GPU ב-Chrome) מוסבר בהרחבה איך Chrome משתמש בשכבות האלה, לצד ה-GPU, כדי לעבד את הדף.

השאלה הפילוסופית

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

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

  • יוצרים חבילה של דפי HTML נפרדים. לכל אחד מהם יש רכיב DOM אחד ופרמוטציה כלשהי של מאפייני CSS שמצורפים אליו.
  • מריצים סקריפט אוטומטי שבכל דף:
    • הפעל את Chrome
    • טעינת דף
    • יוצרים תמונת Skia לדף
    • מריצים כל תמונת Skia שצולמה דרך Skia Benchmark כדי לקבל תזמונים
  • מציגים את כל התזמונים ומתפעלים מהמספרים. (החלק הזה חשוב…)

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

<style>
#example1 {
    background: url(foo.png) top left / 50% 60%;
    padding: 20px; 
    margin-top: 10px;
    margin-right: 20px; 
    text-align: center;
}
</style>
<div id="example1">WOAH</div>

ואחת נוספת, מורכבת יותר

<style>
#example1 {
    background-color:#eee;
    box-shadow: 1px 2px 3px 4px black;
    border-radius: 50%;
    background: radial-gradient(circle closest-corner, white, black);
    padding: 20px; 
    margin-top: 10px;
    margin-right: 20px; 
    text-align: center;
}
</style>
<div id="example1">WOAH</div>

למטה, כגרסה של הדוגמה האחרונה, שבה אנחנו משנים רק את הערך של radial-gradient:

<style>
#example1 
{
    background-color:#eee;
    box-shadow: 1px 2px 3px 4px black;
    border-radius: 50%;
    background: radial-gradient(farthest-side, white, black);
    padding: 20px; 
    margin-top: 10px;
    margin-right: 20px; 
    text-align: center;
}
</style>
<div id="example1" style="padding: 20px; margin-top: 10px;margin-right: 20px; text-align: center;">WOAH</div>

לאחר מכן, כל דף נטען במופע חדש של Chrome (כדי לוודא שהתזמונים לא הושפעו בדרך כלשהי ממצבים לא עדכניים בטעינות חוזרות של הדף), ונוצר Skia Picture (*.SKP) כדי להעריך באילו פקודות Skia נעשה שימוש כדי לצבוע את הדף. אחרי שנוצרים קובצי SKP לכל קובץ HTML, אנחנו מריצים עוד קבוצה כדי להעביר את קובצי ה-‎ *.SKP דרך אפליקציית Skia Benchmark (שנוצרה מקוד המקור של Skia), שמוציאה את הזמן הממוצע שלוקח לעבד את הדף הזה.

הערכת הנתונים

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

תזמונים לכל הצירופים בבדיקה

כל עמודה אנכית מייצגת את זמן הרינדור של דף עם שילוב אחד של מאפייני CSS (מוגדל פי 100; ערך קנה המידה האמיתי של התרשים הזה הוא 0,1.56ms). הרבה קווים יפים, אבל בצורה הזו הם חסרי תועלת. אנחנו צריכים לבצע כריית נתונים כדי למצוא מגמות שימושיות.

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

הזמן שלוקח לצייר רכיב שיש לו רק מאפיין CSS אחד

שנית, וזה מעניין יותר, שילובים של מאפייני CSS יכולים להאריך את זמן הרינדור יותר מאשר סכום החלקים שלהם. מנקודת מבט של משקיף, זה קצת מוזר. היינו מצפים ש-A+B = C, ולא 2.2C. לדוגמה, הוספה של box-shadow ו-border-radius-stroke :

תזמונים לכל הצירופים בבדיקה

החלק המעניין הוא שלא מדובר רק במאפיין box-shadow עצמו, אלא בצירוף הספציפי הזה של הערכים. לדוגמה, למטה מוצגת קבוצה של box-shadow : 50% ו-border-radius עם וריאציות של ערכים.

תזמונים לכל הצירופים בבדיקה

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

איך מוצאים את משקל העיבוד של הדף

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

  1. כדי להבין מה העלות של מאפייני CSS, השתמשו במצב הרינדור הרציף של Chrome בכלי הפיתוח של Chrome.
  2. כדי לזהות בעיות בביצועים, שלבו בדיקות CSS בתהליך הקיים של סקירת הקוד. חפשו מקומות ב-CSS שבהם אתם משתמשים בדברים שידועים ככבדים יותר, כמו מעברי צבע וצללים. תשאלו את עצמכם: האם אני באמת צריך את זה כאן?
  3. אם אתם לא בטוחים, תמיד כדאי לבחור באפשרות שתניב ביצועים טובים יותר. יכול להיות שהמשתמשים לא יזכרו מה רוחב המרווחים בעמודות, אבל הם יזכרו את חוויית הביקור באתר.

סיכום

אחד הדברים הכי מעניינים בניסוי הזה הוא שזמני הטעינה ימשיכו להשתנות בכל גרסה של Chrome (בתקווה שהם יהיו מהירים יותר ;) תוכנת הדפדפן היא שטח פנים שמשתנה כל הזמן. מה שאיטי היום, יכול להיות מהיר מחר. כדי להימנע מהוספת box-shadow: 1px 2px 3px 4px לרכיב שכבר יש לו border-radius:5, אפשר להסיר את המאמר הזה. עם זאת, המסקנה החשובה יותר היא שמאפייני CSS משפיעים ישירות על זמני הרינדור של הדף.

קובצי עזר