איך גדלים של DOM גדולים משפיעים על האינטראקטיביות ומה אפשר לעשות בקשר אליה

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

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

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

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

מתי ה-DOM של דף גדול מדי?

לפי Lighthouse, גודל ה-DOM של דף גדול מדי כשהוא חורג מ-1,400 צמתים. מערכת Lighthouse תתחיל להציג אזהרות כשה-DOM של דף חורג מ-800 צמתים. ניקח לדוגמה את קוד ה-HTML הבא:

<ul>
  <li>List item one.</li>
  <li>List item two.</li>
  <li>List item three.</li>
</ul>

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

איך רכיבי DOM גדולים משפיעות על ביצועי הדפים?

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

  1. במהלך העיבוד הראשוני של הדף. כשמחילים CSS על דף, נוצר מבנה שדומה ל-DOM שנקרא מודל אובייקטים של CSS (CSSOM). ככל שמידת הספציפיות של הסלקטורים ב-CSS עולה, ה-CSSOM נהיה מורכב יותר ונדרש זמן נוסף כדי להפעיל את עבודת הפריסה, העיצוב, ההרכבה והציור שנדרשות כדי להציג את דף האינטרנט אל המסך. העבודה הנוספת הזו מאריכה את זמן האחזור של אינטראקציות שמתרחשות בשלב מוקדם במהלך טעינת הדף.
  2. כשאינטראקציות משנות את ה-DOM, על ידי הוספה או מחיקה של רכיב, או על ידי שינוי תוכן וסגנונות של DOM, העבודה שנדרשת לעיבוד העדכון עלולה לגרום לעבודות יקרות מאוד של פריסה, עיצוב, קומפוזיציה וציור. בדומה לעיבוד הראשוני של הדף, עלייה בספציפיות של הסלקטור ב-CSS יכולה להגביר את עבודת הרינדור כאשר מוסיפים רכיבי HTML אל ה-DOM כתוצאה מאינטראקציה.
  3. כש-JavaScript שולח שאילתה ל-DOM, הפניות לרכיבי DOM נשמרות בזיכרון. לדוגמה, אם קוראים ל-document.querySelectorAll כדי לבחור את כל רכיבי <div> בדף, עלות הזיכרון עשויה להיות משמעותית אם התוצאה מחזירה מספר גדול של רכיבי DOM.
צילום מסך של משימה ארוכה שנגרמה עקב עבודות רינדור מוגזמות בחלונית הביצועים של כלי הפיתוח ל-Chrome. מקבץ הקריאות של המשימה הארוכה מראה זמן משמעותי שהוקדש לחישוב מחדש של סגנונות דף, וגם עיבוד מראש.
משימה ארוכה כפי שמוצג בכלי הפיתוח ל-Chrome. המשימה הארוכה שמוצגת נגרמה על ידי הוספת רכיבי DOM ל-DOM גדול באמצעות JavaScript.

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

איך אפשר למדוד את גודל ה-DOM?

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

שיטה פשוטה יותר כוללת שימוש בלוח JavaScript בכלים למפתחים בכל דפדפן ראשי. כדי לקבל את המספר הכולל של רכיבי HTML ב-DOM, אפשר להשתמש בקוד הבא במסוף אחרי שהדף נטען:

document.querySelectorAll('*').length;

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

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

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

איך אפשר למדוד את מספר רכיבי ה-DOM שהושפעו מאינטראקציה?

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

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

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

איך אפשר להקטין את ה-DOM?

מעבר לבדיקת ה-HTML של האתר לאיתור תגי עיצוב מיותרים, הדרך העיקרית לצמצום גודל ה-DOM היא להפחית את עומק ה-DOM. אות אחד לכך שה-DOM עמוק יותר מדי הוא אם רואים תגי עיצוב שנראים בערך כך בכרטיסייה Elements (רכיבים) בכלים למפתחים בדפדפן:

<div>
  <div>
    <div>
      <div>
        <!-- Contents -->
      </div>
    </div>
  </div>
</div>

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

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

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

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

אסטרטגיות אחרות שכדאי לשקול

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

כדאי לשקול גישה חלופית

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

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

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

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

הגבלת המורכבות של סלקטור ב-CSS

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

שימוש בנכס content-visibility

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

סיכום

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

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

תמונה ראשית (Hero) מ-Unbounce של Louis Reed.