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

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

חישוב הסגנון

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

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

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

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

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

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

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

.title {
  /* styles */
}

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

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

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

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

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

הפחתת מספר הרכיבים בסגנון

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

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

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

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

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

  1. פותחים את כלי הפיתוח.
  2. עוברים לכרטיסייה ביצועים.
  3. לוחצים על הקלטה.
  4. יוצרים אינטראקציה עם הדף.

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

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

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

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

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

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

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

שימוש בבלוק, Element, משנה

שיטות תכנות כמו BEM (Block, Element, Modifier) שמופעלות בבורר יתרונות הביצועים התואמים. לפי BEM, לכל דבר יש מחלקה אחת, ובמקרים שבהם צריך היררכיה, גם ההיררכיה הזו תעבור בתוך שם המחלקה:

.list {
  /* Styles */
}

.list__list-item {
  /* Styles */
}

אם צריך מגביל, כמו בדוגמה של הצאצא האחרון, תוכלו להוסיף אותו כך:

.list__list-item--last-child {
  /* Styles */
}

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

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

משאבים

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