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

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

חישוב הסגנון

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

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

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

Interaction to Next Paint (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. מסמנים את תיבת הסימון נתונים סטטיסטיים של הבורר (אופציונלי).
  4. לוחצים על Record (הקלטה).
  5. לקיים אינטראקציה עם הדף.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

משאבים

תמונה ראשית (Hero) מ-Unbounce, מאת Markus Spiske.