ניפוי באגים שינויים בפריסה

איך לזהות ולתקן שינויים בפריסה.

Katie Hempenius
Katie Hempenius

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

כלים

ממשק API של Deploy Instability API

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

שימוש

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

let cls = 0;
new PerformanceObserver((entryList) => {
  for (const entry of entryList.getEntries()) {
    if (!entry.hadRecentInput) {
      cls += entry.value;
      console.log('Current CLS value:', cls, entry);
    }
  }
}).observe({type: 'layout-shift', buffered: true});

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

  • האפשרות buffered: true מציינת ש- PerformanceObserver צריך לבדוק את רשומת הביצועים של הדפדפן מאגר נתונים זמני לרשומות של ביצועים שנוצרו לפני שהצופה באתחול. כתוצאה מכך, הפריסה של PerformanceObserver תדווח שינויים שהתרחשו גם לפני וגם אחרי האתחול. אני רוצה לשמור את התוכן ב- כשבודקים את יומני המסוף. עומס ראשוני) של שינויי הפריסה יכול לשקף עיכוב בדיווח, במקום אירוע פתאומי של על ידי שינוי הפריסה.
  • כדי למנוע השפעה על הביצועים, PerformanceObserver בהמתנה עד ה-thread לא פעיל כדי לדווח על שינויים בפריסה. כתוצאה מכך, בהתאם לאופן שבו ה-thread הראשי עמוס, יכול להיות שיהיה עיכוב קל בין המועד שבו הפריסה כאשר הוא נרשם במסוף.
  • הסקריפט הזה מתעלם משינויי פריסה שהתרחשו עד 500 אלפיות השנייה לאחר קלט של משתמשים ולכן הן לא נכללות בספירה של CLS.

מדווח מידע על שינויי פריסה באמצעות שילוב של שני ממשקי API: LayoutShift ו- LayoutShiftAttribution ממשקים. כל אחד מהממשקים האלה מוסבר בפירוט בקטעים הבאים.

LayoutShift

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

duration: 0
entryType: "layout-shift"
hadRecentInput: false
lastInputTime: 0
name: ""
sources: (3) [LayoutShiftAttribution, LayoutShiftAttribution, LayoutShiftAttribution]
startTime: 11317.934999999125
value: 0.17508567530168798

הרשומה שלמעלה מציינת שינוי בפריסה שבמהלכו השתנו שלושה רכיבי DOM המיקום. הציון של שינוי הפריסה הזה היה 0.175.

המאפיינים של מופע LayoutShift הרלוונטיים ביותר שינויים בפריסת ניפוי הבאגים:

נכס תיאור
sources במאפיין sources מפורטים רכיבי ה-DOM שעברו במהלך שינוי הפריסה. המערך הזה יכול להכיל עד חמישה מקורות. במקרה שיש יותר מחמישה רכיבים שהושפעו משינוי הפריסה, מדווחים חמשת המקורות הגדולים ביותר (כפי שנמדד על ידי ההשפעה על יציבות הפריסה) לשינויי הפריסה. הדיווח על המידע הזה מתבצע באמצעות ממשק השיוך LayoutShift (יש הסבר מפורט בהמשך).
value הנכס value מדווח על ציון שינוי הפריסה של שינוי פריסה מסוים.
hadRecentInput המאפיין hadRecentInput מציין אם התרחש שינוי פריסה תוך 500 אלפיות השנייה לאחר קלט של משתמשים.
startTime המאפיין startTime מציין מתי התרחש שינוי בפריסה. startTime מצוין באלפיות שנייה ונמדד ביחס לזמן שבו התחילה טעינת הדף.
duration הנכס duration יוגדר תמיד בתור 0. הנכס הזה עובר בירושה מהממשק PerformanceEntry (הממשק LayoutShift מרחיב את הממשק של PerformanceEntry). עם זאת, משך הזמן לא חל על אירועים של שינוי פריסה, ולכן הוא מוגדר ל-0. מידע על הממשק של PerformanceEntry זמין במפרט.

LayoutShiftAttribution

הממשק LayoutShiftAttribution מתאר הזזה יחידה של DOM בודד לרכיב מסוים. אם מספר רכיבים משתנים במהלך שינוי פריסה, הפרמטר sources מכיל מספר רשומות.

לדוגמה, קובץ ה-JSON הבא תואם לשינוי פריסה עם מקור אחד: הזזה למטה של רכיב ה-DOM <div id='banner'> מ-y: 76 אל y:246.

// ...
  "sources": [
    {
      "node": "div#banner",
      "previousRect": {
        "x": 311,
        "y": 76,
        "width": 4,
        "height": 18,
        "top": 76,
        "right": 315,
        "bottom": 94,
        "left": 311
      },
      "currentRect": {
        "x": 311,
        "y": 246,
        "width": 4,
        "height": 18,
        "top": 246,
        "right": 315,
        "bottom": 264,
        "left": 311
      }
    }
  ]

המאפיין node מזהה את רכיב ה-HTML שהשתנה. העברת העכבר מעליה בנכס בכלי הפיתוח מודגש רכיב הדף המתאים.

הנכסים previousRect ו-currentRect מדווחים על הגודל והמיקום של את הצומת.

  • הקואורדינטות x ו-y מדווחות על קואורדינטת ה-x וקואורדינטת ה-y בהתאמה לפינה השמאלית העליונה של הרכיב
  • המאפיינים width ו-height מדווחים על הרוחב והגובה בהתאמה של הרכיב.
  • הנכסים top, right, bottom ו-left מדווחים על x או y לתאם ערכים שתואמים לקצה הנתון של הרכיב. בעוד במילים אחרות, הערך של top שווה ל-y; הערך של bottom שווה ל- y+height

אם כל המאפיינים של previousRect מוגדרים כ-0, המשמעות היא שהרכיב השתנה לתצוגה. אם כל המאפיינים של currentRect מוגדרים כ-0, המשמעות היא שהרכיב הועבר מהתצוגה.

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

דוגמה ראשונה

שינוי הפריסה הזה ידווח ממקור אחד: רכיב ב'. אבל, הגורם הבסיסי לשינוי הפריסה הזה הוא השינוי בגודל של רכיב A.

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

דוגמה שנייה

שינוי הפריסה בדוגמה הזו ידווח בעזרת שני מקורות: רכיב א' ואת אלמנט B. הגורם הבסיסי לשינוי הפריסה הזה הוא השינוי במיקום רכיב א'.

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

דוגמה 3

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

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

דוגמה רביעית

למרות שרכיב ב' משנה את הגודל שלו, אין שינוי בפריסה בדוגמה הזו.

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

בקישור הבא אפשר לראות הדגמה של אופן הדיווח של שינויי DOM על ידי Layout Instability API.

כלי פיתוח

חלונית ביצועים

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

צילום מסך של שינוי הפריסה שמוצג בחלונית &#39;רשת כלי פיתוח&#39;

כדי לראות מידע נוסף על שינוי הפריסה, צריך ללחוץ על שינוי הפריסה ואז פותחים את חלונית ההזזה סיכום. השינויים במאפייני הרכיב מפורטים בפורמט [width, height]; מופיעים שינויים במיקום הרכיב בפורמט [x,y]. המאפיין קיבלנו קלט לאחרונה מציין אם שינוי הפריסה התרחש תוך 500 אלפיות השנייה מאינטראקציה של משתמש.

צילום מסך של ה&#39;סיכום&#39; של כלי הפיתוח כרטיסייה לשינוי פריסה

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

צילום מסך של &#39;יומן האירועים&#39; של כלי הפיתוח כרטיסייה לשינוי פריסה

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

הדגשת אזורים לשינוי הפריסה

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

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

תהליך המחשבה לזיהוי הגורם לשינויים בפריסה

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

זיהוי הגורם לשינוי הפריסה

האירועים הבאים יכולים לגרום לשינויים בפריסה:

  • שינויים במיקום של רכיב DOM
  • שינויים במאפיינים של רכיב DOM
  • הזנה או הסרה של רכיב DOM
  • אנימציות שמפעילות את הפריסה

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

  • האם היה שינוי במיקום או במידות של הרכיב הקודם?
  • האם רכיב DOM נוסף או הוסר לפני הרכיב שהועבר?
  • האם המיקום של הרכיב שהועבר השתנה באופן מפורש?

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

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

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

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

שינויים במיקום של רכיב (שלא נובעים מתנועה של רכיב אחר)

בדרך כלל, שינוי כזה נגרם כתוצאה מ:

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

שינויים במידות של רכיב

בדרך כלל, שינוי כזה נגרם כתוצאה מ:

  • גיליונות סגנונות שנטענים מאוחר או מבטלים סגנונות שהוצהרו בעבר.
  • תמונות ומסגרות iframe ללא מאפייני width ו-height שנטענים אחרי ה"משבצת" שלהם בוצע עיבוד.
  • בלוקים של טקסט ללא המאפיינים width או height שמחליפים גופנים אחרי הטקסט עבר עיבוד.

הוספה או הסרה של רכיבי DOM

פעמים רבות הסיבה לכך היא:

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

אנימציות שמפעילות את הפריסה

אפקטים מסוימים של אנימציה עלולים להפעיל פריסה. דוגמה לכך היא כשרכיבי DOM הם 'מונפשים' באמצעות הגדלת מספר הנכסים כמו top או left במקום להשתמש בשירותים של CSS transform לנכס. איך יוצרים אנימציות CSS בעלות ביצועים גבוהים אפשר לקבל מידע נוסף.

שחזור של שינויי הפריסה

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

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

new PerformanceObserver((entryList) => {
  for (const entry of entryList.getEntries()) {
    if (!entry.hadRecentInput) {
      cls += entry.value;
      debugger;
      console.log('Current CLS value:', cls, entry);
    }
  }
}).observe({type: 'layout-shift', buffered: true});

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