הפחתת ההיקף והמורכבות של חישובי הסגנון

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

חישוב הסגנון

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

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

התפקיד של חישוב מחדש של סגנון בחביון של אינטראקציות

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

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

צמצום המורכבות של כללי הבחירה

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

.title {
  /* styles */
}

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

.box:nth-last-child(-n+1) .title {
  /* styles */
}

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

.final-box-title {
  /* styles */
}

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

צמצום מספר הרכיבים שמוגדרים להם סגנונות

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

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

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

מדידת העלות של חישוב מחדש של סגנון

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

מדידת העלות של חישוב מחדש של סגנון בכלי הפיתוח ל-Chrome

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

  1. פותחים את כלי הפיתוח.
  2. עוברים לכרטיסייה ביצועים.
  3. מסמנים את תיבת הסימון Selector stats (נתונים סטטיסטיים של בורר) (אופציונלי).
  4. לוחצים על הקלטה.
  5. מבצעים אינטראקציה עם הדף.

כשמפסיקים את ההקלטה, רואים משהו כמו התמונה הבאה:

כלי הפיתוח מציג חישובים של סגנונות.
דוח של כלי הפיתוח שבו מוצגים חישובים של סגנונות.

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

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

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

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

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

אם סימנתם את התיבה Selector stats בהגדרות של Performance Panel לפני שהפעלתם את האפשרות trace, בחלק התחתון של החלונית trace תופיע כרטיסייה נוספת עם אותו שם.

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

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

מידע נוסף מופיע במאמרי העזרה בנושא נתונים סטטיסטיים של סלקטורים ב-CSS.

מדידת העלות של חישוב מחדש של סגנון למשתמשים אמיתיים

אם אתם רוצים לדעת כמה זמן לוקח למשתמשים אמיתיים באתר שלכם לחשב מחדש את הסגנון, Long Animation Frames API מספק לכם את הכלים הדרושים לכך. נתונים מ-API הזה נוספו לספריית JavaScript‏ web-vitals, כולל זמן החישוב מחדש של הסגנון.

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

משאבים