מדידת אינטראקציה עד הצבע הבא (INP)

1. מבוא

זהו Codelab אינטראקטיבי שמלמד איך למדוד את המדד מאינטראקציה ועד הצגת התגובה (INP) באמצעות הספרייה web-vitals.

דרישות מוקדמות

מה תלמדו

  • איך מוסיפים את הספרייה web-vitals לדף ומשתמשים בנתוני השיוך שלה.
  • אתם יכולים להשתמש בנתוני השיוך כדי לאבחן איפה ואיך כדאי להתחיל לשפר את INP.

מה נדרש

  • מחשב עם יכולת לשכפל קוד מ-GitHub ולהריץ פקודות npm.
  • כלי לעריכת טקסט.
  • גרסה עדכנית של Chrome כדי שכל מדידות האינטראקציה יפעלו.

2. להגדרה

אחזור והרצה של הקוד

הקוד נמצא במאגר web-vitals-codelabs.

  1. משכפלים את המאגר במסוף: git clone https://github.com/GoogleChromeLabs/web-vitals-codelabs.git.
  2. עוברים לספרייה המשוכפלת: cd web-vitals-codelabs/measuring-inp.
  3. מתקינים את שאר הספריות הדרושות לצורך יצירת ספריות הלקוח: npm ci.
  4. מפעילים את שרת האינטרנט: npm run start.
  5. נכנסים לכתובת http://localhost:8080/ בדפדפן.

ניסיון הדף

בקודלאב הזה נעשה שימוש ב-Gastropodicon (אתר פופולרי למידע על אנטומיה של חלזונות) כדי לבחון בעיות פוטנציאליות ב-INP.

צילום מסך של דף ההדגמה של Gastropodicon

נסו לבצע אינטראקציה עם הדף כדי להבין אילו אינטראקציות איטיות.

3. איך משתמשים בכלי הפיתוח ל-Chrome

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

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

  • בדרך כלל, בעיות ב-INP מתרחשות במכשירים ניידים, לכן מומלץ לעבור להדמיה של מסך נייד.
  • אם אתם בודקים במחשב שולחני או במחשב נייד, סביר להניח שהביצועים יהיו טובים יותר באופן משמעותי מאשר במכשיר נייד אמיתי. כדי לקבל תמונה ריאליסטית יותר של הביצועים, לוחצים על גלגל השיניים בפינה השמאלית העליונה של החלונית ביצועים ובוחרים באפשרות האטה של 4x במעבד (CPU).

צילום מסך של חלונית הביצועים ב-DevTools לצד האפליקציה, כאשר האפשרות 'האטה של 4x במעבד' מסומנת

4. התקנה של מדדי Web Vitals

web-vitals היא ספריית JavaScript למדידת מדדי Web Vitals שהמשתמשים שלכם חווים. אפשר להשתמש בספרייה כדי לתעד את הערכים האלה, ואז לשלוח אותם בתווית (beacon) לנקודת קצה לניתוח (endpoint) לצורך ניתוח מאוחר יותר. המטרה היא להבין מתי ואיפה מתרחשות אינטראקציות איטיות.

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

בשיעור הזה נתקין מ-npm ונטען את הסקריפט ישירות כדי להימנע מהתעמקות בתהליך build ספציפי.

יש שתי גרסאות של web-vitals שאפשר להשתמש בהן:

  • צריך להשתמש בגרסה הרגילה (standard) אם רוצים לעקוב אחרי ערכי המדדים של Core Web Vitals בטעינת דף.
  • ב-build 'Attribution' מתווספים פרטי ניפוי באגים נוספים לכל מדד כדי לאבחן למה המדד מקבל את הערך שהוא מקבל.

כדי למדוד את INP בקודלאב הזה, אנחנו צריכים את build השיוך.

מוסיפים את web-vitals ל-devDependencies של הפרויקט על ידי הפעלת npm install -D web-vitals

מוסיפים את web-vitals לדף:

מוסיפים את גרסת השיוך של הסקריפט לתחתית index.html ומתעדים את התוצאות במסוף:

<script type="module">
  import {onINP} from './node_modules/web-vitals/dist/web-vitals.attribution.js';

  onINP(console.log);
</script>

רוצה לנסות?

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

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

web-vitals מספק את האפשרות reportAllChanges לדיווח מפורט יותר. כשהתכונה מופעלת, לא מדווחים על כל אינטראקציה, אלא רק על כל אינטראקציה איטית יותר מכל אינטראקציה קודמת.

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

<script type="module">
  import {onINP} from './node_modules/web-vitals/dist/web-vitals.attribution.js';

  onINP(console.log, {reportAllChanges: true});
</script>

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

צילום מסך של מסוף DevTools עם הודעות INP שנדפסו בהצלחה

5. מה נכלל בשיוך (Attribution)?

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

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

לוחצים על כן כדי לאשר את קובצי ה-cookie (של הדגמה), ובודקים את נתוני ה-INP שנרשמים עכשיו במסוף DevTools.

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

המידע ברמה העליונה הזה זמין גם בגרסאות הרגילות וגם בגרסאות השיוך של מדדי ה-Web Vitals:

{
  name: 'INP',
  value: 344,
  rating: 'needs-improvement',
  entries: [...],
  id: 'v4-1715732159298-8028729544485',
  navigationType: 'reload',
  attribution: {...},
}

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

עם זאת, כדי לבדוק מה קורה במהלך פרק הזמן הזה, אנחנו מתעניינים בנכס attribution. כדי ליצור את נתוני השיוך, הפונקציה web-vitals מחפשת איזה פריים של אנימציה ארוכה (LoAF) חופף לאירוע הקליק. לאחר מכן, ה-LoAF יכול לספק נתונים מפורטים על הזמן שהיה בשימוש במסגרת הזו, החל מהסקריפטים שפעלו ועד לזמן שהיה בשימוש ב-callback, בסגנון ובפריסה של requestAnimationFrame.

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

attribution: {
  interactionTargetElement: Element,
  interactionTarget: '#confirm',
  interactionType: 'pointer',

  inputDelay: 27,
  processingDuration: 295.6,
  presentationDelay: 21.4,

  processedEventEntries: [...],
  longAnimationFrameEntries: [...],
}

קודם מופיע מידע על הנושא שבו הייתה אינטראקציה:

  • interactionTargetElement: הפניה פעילה לאלמנט שבו התרחשה האינטראקציה (אם האלמנט לא הוסר מ-DOM).
  • interactionTarget: בורר לאיתור הרכיב בדף.

לאחר מכן, התזמון מפורט באופן כללי:

  • inputDelay: הזמן שחלף מרגע שהמשתמש התחיל את האינטראקציה (לדוגמה, לחץ על העכבר) ועד לרגע שבו התחיל לפעול מאזין האירועים של האינטראקציה הזו. במקרה הזה, עיכוב הקלט היה רק כ-27 אלפיות השנייה, גם כשהצמצום של המעבד היה מופעל.
  • processingDuration: הזמן שנדרש למעקב האירועים להריץ עד לסיום. לרוב, בדפים יש כמה מאזינים לאירוע יחיד (לדוגמה, pointerdown,‏ pointerup ו-click). אם כולם פועלים באותו פריים של אנימציה, הם ימוזגו לזמן הזה. במקרה הזה, משך העיבוד הוא 295.6 אלפיות השנייה – רוב זמן ה-INP.
  • presentationDelay: הזמן מהרגע שבו פונקציות ה-event listener הושלמו עד שהדפדפן סיים לצייר את המסגרת הבאה. במקרה הזה, 21.4 אלפיות השנייה.

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

אם נעמיק עוד קצת, נראה שה-processedEventEntries מכיל חמישה אירועים, בניגוד לאירוע היחיד במערך entries של INP ברמה העליונה. מה ההבדל?

processedEventEntries: [
  {
    name: 'mouseover',
    entryType: 'event',
    startTime: 1801.6,
    duration: 344,
    processingStart: 1825.3,
    processingEnd: 1825.3,
    cancelable: true
  },
  {
    name: 'mousedown',
    entryType: 'event',
    startTime: 1801.6,
    duration: 344,
    processingStart: 1825.3,
    processingEnd: 1825.3,
    cancelable: true
  },
  {name: 'mousedown', ...},
  {name: 'mouseup', ...},
  {name: 'click', ...},
],

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

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

longAnimationFrameEntries

הרחבת הרשומה ב-LoAF:

longAnimationFrameEntries: [{
  name: 'long-animation-frame',
  startTime: 1823,
  duration: 319,

  renderStart: 2139.5,
  styleAndLayoutStart: 2139.7,
  firstUIEventTimestamp: 1801.6,
  blockingDuration: 268,

  scripts: [{...}]
}],

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

scripts: [{
  name: 'script',
  invoker: 'BUTTON#confirm.onclick',
  invokerType: 'event-listener',

  startTime: 1828.6,
  executionStart: 1828.6,
  duration: 294,

  sourceURL: 'http://localhost:8080/third-party/cmp.js',
  sourceFunctionName: '',
  sourceCharPosition: 1144
}]

במקרה כזה, אפשר לראות שהזמן הושפע בעיקר מ-event-listener יחיד, שהופעל ב-BUTTON#confirm.onclick. אנחנו יכולים לראות גם את כתובת ה-URL של מקור הסקריפט ואת מיקום התו של המקום שבו הפונקציה הוגדרה.

סיכום

מה אפשר לקבוע לגבי הפנייה הזו על סמך נתוני השיוך האלה?

  • האינטראקציה הופעלה על ידי קליק על רכיב button#confirm (מ-attribution.interactionTarget ומנכס invoker ברשומה של שיוך סקריפט).
  • הזמן הוצא בעיקר על ביצוע של מאזיני אירועים (מ-attribution.processingDuration בהשוואה למדד הכולל value).
  • קוד ה-event listener האיטי מתחיל מ-click listener שמוגדר ב-third-party/cmp.js (מ-scripts.sourceURL).

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

6. פונקציות event listener מרובות

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

מתחילים להקליד בתיבת החיפוש. מה מוצג בנתוני השיוך מה דעתך?

נתוני שיוך (Attribution)

קודם כול, סקירה ברמה גבוהה של דוגמה אחת לבדיקת ההדגמה:

{
  name: 'INP',
  value: 1072,
  rating: 'poor',
  attribution: {
    interactionTargetElement: Element,
    interactionTarget: '#search-terms',
    interactionType: 'keyboard',

    inputDelay: 3.3,
    processingDuration: 1060.6,
    presentationDelay: 8.1,

    processedEventEntries: [...],
    longAnimationFrameEntries: [...],
  }
}

זהו ערך INP נמוך (כשהצמצום של קצב העיבוד מופעל) מאינטראקציה עם מקלדת עם המרכיב input#search-terms. רוב הזמן – 1,061 אלפיות שנייה מתוך 1,072 אלפיות שנייה של INP כולל – הושפע ממשך הזמן של העיבוד.

עם זאת, הרשומות של scripts מעניינות יותר.

Layout thrashing

הרשומה הראשונה במערך scripts מספקת לנו הקשר חשוב:

scripts: [{
  name: 'script',
  invoker: 'BUTTON#confirm.onclick',
  invokerType: 'event-listener',

  startTime: 4875.6,
  executionStart: 4875.6,
  duration: 497,
  forcedStyleAndLayoutDuration: 388,

  sourceURL: 'http://localhost:8080/js/index.js',
  sourceFunctionName: 'handleSearch',
  sourceCharPosition: 940
},
...]

רוב משך העיבוד מתרחש במהלך ביצוע הסקריפט הזה, שהוא מאזין input (מבצע ההפעלה הוא INPUT#search-terms.oninput). שם הפונקציה מצוין (handleSearch), וכך גם מיקום התו בתוך קובץ המקור index.js.

עם זאת, יש נכס חדש: forcedStyleAndLayoutDuration. זהו הזמן שחלף במהלך ההפעלה הזו של הסקריפט, שבה הדפדפן נאלץ לעצב מחדש את הדף. במילים אחרות, 78% מהזמן – 388 אלפיות השנייה מתוך 497 – שהוקדשו להפעלת מאזין האירועים הזה הוקדשו בפועל לטרחה בפריסת האתר.

זו צריכה להיות תיקון בעדיפות גבוהה.

מאזינים חוזרים

בנפרד, אין שום דבר יוצא דופן בשתי רשומות הסקריפט הבאות:

scripts: [...,
{
  name: 'script',
  invoker: '#document.onkeyup',
  invokerType: 'event-listener',

  startTime: 5375.3,
  executionStart: 5375.3,
  duration: 124,

  sourceURL: 'http://localhost:8080/js/index.js',
  sourceFunctionName: '',
  sourceCharPosition: 1526,
},
{
  name: 'script',
  invoker: '#document.onkeyup',
  invokerType: 'event-listener',

  startTime: 5673.9,
  executionStart: 5673.9,
  duration: 95,

  sourceURL: 'http://localhost:8080/js/index.js',
  sourceFunctionName: '',
  sourceCharPosition: 1526
}]

שתי הרשומות הן מאזינים של keyup, שפועלים בזה אחר זה. המאזינים הם פונקציות אנונימיות (לכן לא מדווחים על שום דבר בנכס sourceFunctionName), אבל עדיין יש לנו קובץ מקור ומיקום תו, כך שאנחנו יכולים למצוא את המיקום של הקוד.

המוזר הוא ששניהם מאותו קובץ מקור ומאותה מיקום תו.

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

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

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

7. השהיה לאחר קלט

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

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

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

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

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

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

זו דוגמה לשיוך שמתקבל רק מהתמקדות בתיבת החיפוש במהלך נטישה מסוג 'צביקה':

{
  name: 'INP',
  value: 728,
  rating: 'poor',

  attribution: {
    interactionTargetElement: Element,
    interactionTarget: '#search-terms',
    interactionType: 'pointer',

    inputDelay: 702.3,
    processingDuration: 4.9,
    presentationDelay: 20.8,

    longAnimationFrameEntries: [{
      name: 'long-animation-frame',
      startTime: 2064.8,
      duration: 790,

      renderStart: 2065,
      styleAndLayoutStart: 2854.2,
      firstUIEventTimestamp: 0,
      blockingDuration: 740,

      scripts: [{...}]
    }]
  }
}

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

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

כדי לפתור את הבעיה, אפשר להשתמש באפשרות 'הוספת סקריפט ל-LoAF':

scripts: [{
  name: 'script',
  invoker: 'SPAN.onanimationiteration',
  invokerType: 'event-listener',

  startTime: 2065,
  executionStart: 2065,
  duration: 788,

  sourceURL: 'http://localhost:8080/js/index.js',
  sourceFunctionName: 'cryptodaphneCoinHandler',
  sourceCharPosition: 1831
}]

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

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

8. עיכוב בהצגה: כשעדכון לא מוצג

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

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

כיצד הכלי הזה נראה?

{
  name: 'INP',
  value: 376,
  rating: 'needs-improvement',
  delta: 352,

  attribution: {
    interactionTarget: '#sidenav-button>svg',
    interactionType: 'pointer',

    inputDelay: 12.8,
    processingDuration: 14.7,
    presentationDelay: 348.5,

    longAnimationFrameEntries: [{
      name: 'long-animation-frame',
      startTime: 651,
      duration: 365,

      renderStart: 673.2,
      styleAndLayoutStart: 1004.3,
      firstUIEventTimestamp: 138.6,
      blockingDuration: 315,

      scripts: [{...}]
    }]
  }
}

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

scripts: [{
  entryType: 'script',
  invoker: 'FrameRequestCallback',
  invokerType: 'user-callback',

  startTime: 673.8,
  executionStart: 673.8,
  duration: 330,

  sourceURL: 'http://localhost:8080/js/side-nav.js',
  sourceFunctionName: '',
  sourceCharPosition: 1193,
}]

כשבודקים את הרשומה היחידה במערך scripts, רואים שהזמן חלף ב-user-callback מ-FrameRequestCallback. הפעם העיכוב בשידור המצגת נובע מקריאה חוזרת (call back) של requestAnimationFrame.

9. סיכום

צבירת נתוני שדה

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

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

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

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

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

שיוך בכל מקום

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

עכשיו אתם מוכנים להשתמש בנתוני שיוך של INP בכל אתר.

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

const script = document.createElement('script');
script.src = 'https://unpkg.com/web-vitals@4/dist/web-vitals.attribution.iife.js';
script.onload = function () {
  webVitals.onINP(console.log, {reportAllChanges: true});
};
document.head.appendChild(script);

מידע נוסף