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

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

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

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

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

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

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

הפחתת המורכבות של הסלקטורים

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

.title {
  /* styles */
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

משאבים