איך למצוא אינטראקציות איטיות בנתוני השדה של האתר כדי לשפר את מהירות התגובה לאינטראקציה באתר (INP).
נתוני שטח הם נתונים שמראים מהי חוויית המשתמשים בפועל באתר שלכם. הוא מאפשר לזהות בעיות שאי אפשר למצוא בנתונים בסביבת ניסוי בלבד. בכל הנוגע למהירות התגובה לאינטראקציה באתר (INP), נתוני השדה חיוניים לזיהוי אינטראקציות איטיות, ומספקים רמזים חיוניים שיעזרו לכם לתקן אותן.
במדריך הזה נסביר איך להעריך במהירות את ה-INP של האתר באמצעות נתוני שדה מהדוח על חוויית המשתמש ב-Chrome (CrUX), כדי לבדוק אם יש באתר בעיות שקשורות ל-INP. בהמשך נסביר איך להשתמש בגרסת השיוך של ספריית JavaScript של web-vitals – ובתובנות החדשות שהיא מספקת מ-Long Animation Frames API (LoAF) – כדי לאסוף ולפרש נתונים מהשטח לגבי אינטראקציות איטיות באתר.
מתחילים עם CrUX כדי להעריך את ה-INP של האתר
אם אתם לא אוספים נתוני שטח מהמשתמשים באתר, CrUX יכול להיות נקודת התחלה טובה. דוח CrUX אוסף נתוני שטח ממשתמשי Chrome אמיתיים שהביעו הסכמה לשליחת נתוני טלמטריה.
נתוני CrUX מוצגים בכמה אזורים שונים, בהתאם להיקף המידע שאתם מחפשים. דוח CrUX יכול לספק נתונים על INP ועל מדדי ליבה אחרים לבדיקת חוויית המשתמש באתר (Core Web Vitals) עבור:
- דפים ספציפיים ומקורות שלמים באמצעות PageSpeed Insights.
- סוגי דפים. לדוגמה, בהרבה אתרי מסחר אלקטרוני יש סוגים של דפי פרטי מוצר ודפי כרטיסי מוצר. אתם יכולים לקבל נתוני CrUX לסוגי דפים ייחודיים ב-Search Console.
כדי להתחיל, אתם יכולים להזין את כתובת ה-URL של האתר שלכם ב-PageSpeed Insights. אחרי שמזינים את כתובת ה-URL, נתוני השדה שלה (אם הם זמינים) יוצגו בכמה מדדים, כולל INP. אתם יכולים גם להשתמש במתגים כדי לבדוק את ערכי ה-INP שלכם במאפיינים של ניידים ומחשבים.
הנתונים האלה שימושיים כי הם מצביעים על בעיה. עם זאת, CrUX לא יכול להגיד לכם מה גורם לבעיות. יש הרבה פתרונות זמינים למעקב אחר משתמשים אמיתיים (RUM) שיעזרו לכם לאסוף נתוני שדה משלכם מהמשתמשים באתר כדי לענות על השאלה הזו. אפשרות אחת היא לאסוף את נתוני השדה בעצמכם באמצעות ספריית JavaScript של מדדי חוויית המשתמש באתר.
איסוף נתונים מהשטח באמצעות ספריית JavaScript של web-vitals
ספריית JavaScript של web-vitals היא סקריפט שאפשר לטעון באתר כדי לאסוף נתוני שדה מהמשתמשים באתר. אפשר להשתמש בה כדי לתעד מספר מדדים, כולל INP בדפדפנים שתומכים בה.
אפשר להשתמש בגרסה הרגילה של ספריית web-vitals כדי לקבל נתוני INP בסיסיים ממשתמשים בשטח:
import {onINP} from 'web-vitals';
onINP(({name, value, rating}) => {
console.log(name); // 'INP'
console.log(value); // 512
console.log(rating); // 'poor'
});
כדי לנתח את נתוני השדה מהמשתמשים, צריך לשלוח את הנתונים האלה לאנשהו:
import {onINP} from 'web-vitals';
onINP(({name, value, rating}) => {
// Prepare JSON to be sent for collection. Note that
// you can add anything else you'd want to collect here:
const body = JSON.stringify({name, value, rating});
// Use `sendBeacon` to send data to an analytics endpoint.
// For Google Analytics, see https://github.com/GoogleChrome/web-vitals#send-the-results-to-google-analytics.
navigator.sendBeacon('/analytics', body);
});
עם זאת, הנתונים האלה לבדם לא מספקים הרבה יותר מידע ממה ש-CrUX מספק. כאן נכנס לתמונה ה-build של השיוך בספריית web-vitals.
איך להרחיב את היכולות בעזרת גרסת השיוך של ספריית web-vitals
גרסת השיוך של ספריית web-vitals מציגה נתונים נוספים שאפשר לקבל ממשתמשים בשטח, כדי לעזור לכם לפתור בעיות באינטראקציות בעייתיות שמשפיעות על ה-INP של האתר. אפשר לגשת לנתונים האלה דרך האובייקט attribution שמופיע ב-method onINP() של הספרייה:
import {onINP} from 'web-vitals/attribution';
onINP(({name, value, rating, attribution}) => {
console.log(name); // 'INP'
console.log(value); // 56
console.log(rating); // 'good'
console.log(attribution); // Attribution data object
});
בנוסף ל-INP של הדף עצמו, ה-attribution build מספק הרבה נתונים שיכולים לעזור לכם להבין את הסיבות לאינטראקציות איטיות, כולל החלק באינטראקציה שבו כדאי להתמקד. הוא יכול לעזור לכם לענות על שאלות חשובות, כמו:
- "האם המשתמש ביצע אינטראקציה עם הדף בזמן שהוא נטען?"
- "האם הגורמים המטפלים באירועים של האינטראקציה פעלו במשך זמן רב?"
- "האם חל עיכוב בהפעלת הקוד של הגורם המטפל באירועים של האינטראקציה? אם כן, מה עוד קרה בשרשור הראשי באותו זמן?"
- "האם האינטראקציה גרמה להרבה עבודת רינדור שעיכבה את הצגת הפריים הבא?"
בטבלה הבאה מוצגים חלק מנתוני השיוך הבסיסיים שאפשר לקבל מהספרייה, שיכולים לעזור לכם להבין כמה מהגורמים ברמה גבוהה לאינטראקציות איטיות באתר:
מפתח אובייקט אחד (attribution)
|
נתונים |
|---|---|
interactionTarget
|
סלקטור ב-CSS שמצביע על הרכיב שיצר את ערך ה-INP של הדף – לדוגמה, button#save.
|
interactionType
|
סוג האינטראקציה, מקליקים, מהקשות או מקלט מקלדת. |
inputDelay*
|
העיכוב אחרי קלט של האינטראקציה. |
processingDuration*
|
הזמן שחולף מהרגע שבו רכיב ה-event listener הראשון מתחיל לפעול בתגובה לאינטראקציה של המשתמש, ועד שכל העיבוד של רכיבי ה-event listener מסתיים. |
presentationDelay*
|
העיכוב בהצגה של האינטראקציה, שמתרחש החל מהרגע שבו הגורמים המטפלים באירועים מסיימים את הפעולה ועד למועד שבו הפריים הבא מוצג. |
longAnimationFrameEntries*
|
רשומות מה-LoAF שמשויכות לאינטראקציה. מידע נוסף מופיע בקטע הבא. |
החל מגרסה 4 של ספריית web-vitals, אתם יכולים לקבל תובנות מעמיקות עוד יותר לגבי אינטראקציות בעייתיות באמצעות הנתונים שהיא מספקת עם פירוט של שלבי INP (עיכוב בקלט, משך העיבוד ועיכוב בהצגה) ו-Long Animation Frames API (LoAF).
Long Animation Frames API (LoAF)
ניפוי באגים של אינטראקציות באמצעות נתוני שדה הוא משימה מאתגרת. עם זאת, בעזרת הנתונים מ-LoAF, עכשיו אפשר לקבל תובנות טובות יותר לגבי הגורמים לאינטראקציות איטיות, כי LoAF חושף מספר תזמונים מפורטים ונתונים אחרים שבהם אתם יכולים להשתמש כדי לזהות גורמים מדויקים – וחשוב מכך, איפה מקור הבעיה בקוד של האתר.
גרסת השיוך (Attribution) של ספריית web-vitals חושפת מערך של רשומות LoAF במפתח longAnimationFrameEntries של האובייקט attribution. בטבלה הבאה מפורטים כמה נתונים חשובים שאפשר למצוא בכל רשומה של LoAF:
| מפתח אובייקט של רשומת LoAF | נתונים |
|---|---|
duration
|
משך הזמן של פריים האנימציה עם הטעינה הארוכה, עד לסיום הפריסה, אבל לא כולל צביעה וקומפוזיציה. |
blockingDuration
|
משך הזמן הכולל בפריים שבו הדפדפן לא הצליח להגיב במהירות בגלל משימות שנמשכו הרבה זמן. זמן החסימה הזה יכול לכלול משימות שנמשכות הרבה זמן שמריצות JavaScript, וגם כל משימת רינדור ארוכה לאחר מכן בפריים. |
firstUIEventTimestamp
|
חותמת הזמן של מועד הוספת האירוע לתור במהלך הפריים. האירוע הזה שימושי כדי להבין מתי מתחיל העיכוב בקלט של אינטראקציה. |
startTime
|
חותמת הזמן של תחילת הפריים. |
renderStart
|
מתי התחילה עבודת העיבוד של הפריים. זה כולל קריאות חוזרות (callbacks) של requestAnimationFrame (וקריאות חוזרות של ResizeObserver אם רלוונטי), אבל יכול להיות שלפני שמתחילה עבודה כלשהי על הסגנון או הפריסה.
|
styleAndLayoutStart
|
כשמתבצעת עבודה על הסגנון או הפריסה בפריים. המידע הזה יכול לעזור לכם להבין כמה זמן ייקח לעצב את הסגנון או הפריסה, כשמביאים בחשבון חותמות זמן זמינות אחרות. |
scripts
|
מערך של פריטים שמכילים מידע על שיוך הסקריפט שתורם ל-INP של הדף. |
blockingDuration).
כל המידע הזה יכול לספר לכם הרבה על מה שגורם לאינטראקציה איטית, אבל המערך scripts שרשומות LoAF מציגות אמור לעניין במיוחד:
| מפתח אובייקט של שיוך סקריפט | נתונים |
|---|---|
invoker
|
המפעיל. הערך הזה יכול להשתנות בהתאם לסוג המפעיל שמתואר בשורה הבאה. דוגמאות לגורמים מפעילים יכולות להיות ערכים כמו 'IMG#id.onload', 'Window.requestAnimationFrame' או 'Response.json.then'. |
invokerType
|
סוג המפעיל. הערכים האפשריים: 'user-callback', 'event-listener', 'resolve-promise', 'reject-promise', 'classic-script' או 'module-script'.
|
sourceURL
|
כתובת ה-URL של הסקריפט שממנו הגיע פריים האנימציה עם הטעינה הארוכה. |
sourceCharPosition
|
מיקום התו בתסריט שזוהה על ידי sourceURL.
|
sourceFunctionName
|
שם הפונקציה בסקריפט שזוהה. |
כל רשומה במערך הזה מכילה את הנתונים שמוצגים בטבלה הזו, שמספקת מידע על הסקריפט שהיה אחראי לאינטראקציה האיטית – ואיך הוא היה אחראי.
איך למדוד ולזהות סיבות נפוצות לאינטראקציות איטיות
כדי להמחיש איך אפשר להשתמש במידע הזה, המדריך הזה יסביר איך אתם יכולים להשתמש בנתוני LoAF שמוצגים בספרייה web-vitals כדי לזהות כמה מהגורמים לאינטראקציות איטיות.
משך עיבוד ארוך
משך העיבוד של אינטראקציה הוא הזמן שנדרש כדי להשלים את ההרצה של פונקציות ה-callback הרשומות של הגורם המטפל באירועים של האינטראקציה, וכל דבר אחר שעשוי לקרות ביניהן. ספריית web-vitals מציגה משכי עיבוד ארוכים:
import {onINP} from 'web-vitals/attribution';
onINP(({name, value, attribution}) => {
const {processingDuration} = attribution; // 512.5
});
טבעי לחשוב שהסיבה העיקרית לאינטראקציה איטית היא שלקח יותר מדי זמן להריץ את הקוד של הגורם המטפל באירועים, אבל זה לא תמיד המצב. אחרי שמוודאים שזו הבעיה, אפשר להעמיק בנתוני LoAF:
import {onINP} from 'web-vitals/attribution';
onINP(({name, value, attribution}) => {
const {processingDuration} = attribution; // 512.5
// Get the longest script from LoAF covering `processingDuration`:
const loaf = attribution.longAnimationFrameEntries.at(-1);
const script = loaf?.scripts.toSorted((a, b) => b.duration - a.duration)[0];
if (script) {
// Get attribution for the long-running event handler:
const {invokerType} = script; // 'event-listener'
const {invoker} = script; // 'BUTTON#update.onclick'
const {sourceURL} = script; // 'https://example.com/app.js'
const {sourceCharPosition} = script; // 83
const {sourceFunctionName} = script; // 'update'
}
});
כפי שניתן לראות בקטע הקוד הקודם, אפשר לעבוד עם נתוני LoAF כדי לאתר את הסיבה המדויקת לאינטראקציה עם ערכים גבוהים של משך העיבוד, כולל:
- הרכיב ורכיב ה-event listener הרשום שלו.
- קובץ הסקריפט – ומיקום התו בתוכו – שמכיל את הקוד של הגורם המטפל באירועים שפועל במשך זמן רב.
- שם הפונקציה.
סוג הנתונים הזה הוא בעל ערך רב. אתם כבר לא צריכים לעשות את העבודה הקשה של לגלות בדיוק איזו אינטראקציה – או איזה מהגורמים המטפלים באירועים שלה – הייתה אחראית לערכים הגבוהים של משך העיבוד. בנוסף, מכיוון שסקריפטים של צד שלישי יכולים לעיתים קרובות לרשום גורמים מטפלים באירועים משלהם, אתם יכולים לקבוע אם הקוד שלכם הוא זה שאחראי לכך. בכל הנוגע לקוד שיש לכם שליטה עליו, כדאי לבדוק איך לבצע אופטימיזציה של משימות שנמשכות הרבה זמן.
עיכובים ארוכים בקלט
למרות שגורמים מטפלים באירועים שפועלים לאורך זמן הם נפוצים, יש חלקים אחרים באינטראקציה שצריך להביא בחשבון. החלק הראשון מתרחש לפני משך העיבוד, והוא נקרא השהיית קלט. זהו משך הזמן מהרגע שבו המשתמש יוזם את האינטראקציה ועד לרגע שבו מתחילות לפעול פונקציות ה-callback של הגורם המטפל באירועים. זה קורה כשהשרשור הראשי כבר מעבד משימה אחרת. גרסת ה-attribution של ספריית web-vitals יכולה להראות לכם את משך העיכוב בקלט של אינטראקציה:
import {onINP} from 'web-vitals/attribution';
onINP(({name, value, attribution}) => {
const {inputDelay} = attribution; // 125.59439536
});
אם אתם מבחינים שבאינטראקציות מסוימות יש עיכובים ארוכים בקלט, תצטרכו להבין מה קרה בדף בזמן האינטראקציה שגרם לעיכוב הארוך בקלט. לעיתים קרובות, הסיבה היא שהאינטראקציה התרחשה בזמן שהדף נטען, או אחרי שהוא נטען.
האם זה קרה במהלך טעינת הדף?
ה-thread הראשי בדרך כלל הכי עמוס כשהדף נטען. בזמן הזה, כל מיני משימות נכנסות לתור ומעובדות, ואם המשתמש מנסה לבצע אינטראקציה עם הדף בזמן שכל העבודה הזו מתבצעת, זה יכול לעכב את האינטראקציה. דפים שטוענים הרבה JavaScript יכולים להתחיל לקמפל ולהעריך סקריפטים, וגם להפעיל פונקציות שמכינות את הדף לאינטראקציות של משתמשים. הפעילות הזו יכולה להפריע אם המשתמש מבצע פעולה בזמן שהיא מתרחשת. אתם יכולים לבדוק אם זה קורה למשתמשים באתר שלכם:
import {onINP} from 'web-vitals/attribution';
onINP(({name, value, attribution}) => {
const {inputDelay} = attribution; // 125.59439536
// Get the longest script from the first LoAF entry:
const loaf = attribution.longAnimationFrameEntries[0];
const script = loaf?.scripts.toSorted((a, b) => b.duration - a.duration)[0];
if (script) {
// Invoker types can describe if script eval blocked the main thread:
const {invokerType} = script; // 'classic-script' | 'module-script'
const {sourceLocation} = script; // 'https://example.com/app.js'
}
});
אם אתם מתעדים את הנתונים האלה בשדה ורואים עיכובים ארוכים בקלט וסוגי מפעילים של 'classic-script' או 'module-script', אפשר להניח שלוקח הרבה זמן להעריך את הסקריפטים באתר, והם חוסמים את ה-main thread למשך זמן ארוך מספיק כדי לעכב אינטראקציות. כדי לצמצם את זמן החסימה, אפשר לפצל את הסקריפטים לחבילות קטנות יותר, לדחות את הטעינה של קוד שלא נמצא בשימוש בשלב הראשוני למועד מאוחר יותר, ולבדוק אם יש באתר קוד שלא נמצא בשימוש שאפשר להסיר לגמרי.
האם זה קרה אחרי טעינת הדף?
עיכובים בקלט מתרחשים לעיתים קרובות בזמן שהדף נטען, אבל הם יכולים להתרחש גם אחרי שהדף נטען, מסיבה אחרת לגמרי. גורמים נפוצים לעיכובים בקלט אחרי טעינת הדף יכולים להיות קוד שפועל מדי פעם בגלל קריאה קודמת ל-setInterval, או אפילו קריאות חוזרות (callbacks) של אירועים שהיו בתור להפעלה מוקדמת יותר, ועדיין נמצאות בתהליך עיבוד.
import {onINP} from 'web-vitals/attribution';
onINP(({name, value, attribution}) => {
const {inputDelay} = attribution; // 125.59439536
// Get the longest script from the first LoAF entry:
const loaf = attribution.longAnimationFrameEntries[0];
const script = loaf?.scripts.toSorted((a, b) => b.duration - a.duration)[0];
if (script) {
const {invokerType} = script; // 'user-callback'
const {sourceURL} = script; // 'https://example.com/app.js'
const {sourceCharPosition} = script; // 83
const {sourceFunctionName} = script; // 'update'
}
});
כמו במקרה של פתרון בעיות שקשורות לערכים גבוהים של משך העיבוד, עיכובים גבוהים בקלט שנובעים מהסיבות שצוינו קודם יספקו לכם נתונים מפורטים של שיוך סקריפטים. עם זאת, סוג הגורם המפעיל ישתנה בהתאם לאופי העבודה שעיכבה את האינטראקציה:
-
'user-callback'מציין שהמשימה החוסמת הייתה מ-setInterval, מ-setTimeoutאו אפילו מ-requestAnimationFrame. - הסמל
'event-listener'מציין שהמשימה שחוסמת את התהליך היא מקלט קודם שהועבר לתור ועדיין נמצא בעיבוד. 'resolve-promise'ו-'reject-promise'מציינים שהמשימה החוסמת הייתה חלק מעבודה אסינכרונית שהתחילה מוקדם יותר, והושלמה או נדחתה בזמן שהמשתמש ניסה לבצע אינטראקציה עם הדף, מה שגרם לעיכוב באינטראקציה.
בכל מקרה, נתוני השיוך של הסקריפט יתנו לכם מושג איפה להתחיל לחפש, ויעזרו לכם להבין אם העיכוב בקלט נגרם בגלל הקוד שלכם או בגלל סקריפט של צד שלישי.
עיכובים ארוכים בהצגת התגובה
עיכובים בהצגה הם השלב האחרון של אינטראקציה, והם מתחילים כשהגורמים המטפלים באירועים של האינטראקציה מסתיימים, עד לנקודה שבה הפריים הבא צויר. הם מתרחשים כשהעבודה בגורם המטפל באירועים, שנובעת מאינטראקציה, משנה את המצב החזותי של ממשק המשתמש. כמו במקרה של משך העיבוד ועיכובים בקלט, ספריית web-vitals יכולה להראות לכם כמה זמן נמשך העיכוב בהצגה של אינטראקציה:
import {onINP} from 'web-vitals/attribution';
onINP(({name, value, attribution}) => {
const {presentationDelay} = attribution; // 113.32307691
});
אם אתם מתעדים את הנתונים האלה ורואים עיכובים ארוכים בהצגה של אינטראקציות שתורמות ל-INP של האתר, יכולות להיות לכך סיבות שונות. הנה כמה סיבות שכדאי לשים לב אליהן.
עבודה יקרה על סגנון ופריסה
עיכובים ארוכים בהצגה יכולים לנבוע מחישוב מחדש של סגנונות ומעבודה על פריסה, שנגרמים מכמה סיבות, כולל סלקטורים מורכבים ב-CSS ונפחי DOM גדולים. אתם יכולים למדוד את משך העבודה הזו באמצעות תזמוני LoAF שמופיעים בספריית web-vitals:
import {onINP} from 'web-vitals/attribution';
onINP(({name, value, attribution}) => {
const {presentationDelay} = attribution; // 113.32307691
// Get the longest script from the last LoAF entry:
const loaf = attribution.longAnimationFrameEntries.at(-1);
const script = loaf?.scripts.toSorted((a, b) => b.duration - a.duration)[0];
// Get necessary timings:
const {startTime} = loaf; // 2120.5
const {duration} = loaf; // 1002
// Figure out the ending timestamp of the frame (approximate):
const endTime = startTime + duration; // 3122.5
// Get the start timestamp of the frame's style/layout work:
const {styleAndLayoutStart} = loaf; // 3011.17692309
// Calculate the total style/layout duration:
const styleLayoutDuration = endTime - styleAndLayoutStart; // 111.32307691
if (script) {
// Get attribution for the event handler that triggered
// the long-running style and layout operation:
const {invokerType} = script; // 'event-listener'
const {invoker} = script; // 'BUTTON#update.onclick'
const {sourceURL} = script; // 'https://example.com/app.js'
const {sourceCharPosition} = script; // 83
const {sourceFunctionName} = script; // 'update'
}
});
ה-LoAF לא יציין את משך הזמן של עבודת הסגנון והפריסה של פריים, אבל הוא יציין מתי היא התחילה. בעזרת חותמת הזמן הזו של ההתחלה, אתם יכולים להשתמש בנתונים אחרים מ-LoAF כדי לחשב משך זמן מדויק של העבודה הזו. כדי לעשות את זה, אתם צריכים לקבוע את שעת הסיום של הפריים, ולהחסיר ממנה את חותמת הזמן של ההתחלה של עבודת הסגנון והפריסה.
קריאות חוזרות (callbacks) ארוכות של requestAnimationFrame
אחת מהסיבות האפשריות לעיכובים ארוכים בהצגה היא עבודה מוגזמת שנעשית בקריאה חוזרת (callback) של requestAnimationFrame. התוכן של הקריאה החוזרת הזו מופעל אחרי שהגורמים המטפלים באירועים מסיימים לפעול, אבל ממש לפני החישוב מחדש של הסגנון והעבודה על הפריסה.
אם העבודה שמתבצעת בתוך הקריאות החוזרות האלה מורכבת, יכול להיות שייקח הרבה זמן להשלים אותן. אם אתם חושדים שערכים גבוהים של עיכוב בהצגה נובעים מעבודה שאתם מבצעים עם requestAnimationFrame, אתם יכולים להשתמש בנתוני LoAF שמוצגים בספריית web-vitals כדי לזהות את התרחישים האלה:
onINP(({name, value, attribution}) => {
const {presentationDelay} = attribution; // 543.1999999880791
// Get the longest script from the last LoAF entry:
const loaf = attribution.longAnimationFrameEntries.at(-1);
const script = loaf?.scripts.toSorted((a, b) => b.duration - a.duration)[0];
// Get the render start time and when style and layout began:
const {renderStart} = loaf; // 2489
const {styleAndLayoutStart} = loaf; // 2989.5999999940395
// Calculate the `requestAnimationFrame` callback's duration:
const rafDuration = styleAndLayoutStart - renderStart; // 500.59999999403954
if (script) {
// Get attribution for the event handler that triggered
// the long-running requestAnimationFrame callback:
const {invokerType} = script; // 'user-callback'
const {invoker} = script; // 'FrameRequestCallback'
const {sourceURL} = script; // 'https://example.com/app.js'
const {sourceCharPosition} = script; // 83
const {sourceFunctionName} = script; // 'update'
}
});
אם אתם רואים שחלק משמעותי מזמן ההשהיה בהצגה מושקע בקריאה חוזרת (callback) של requestAnimationFrame, ודאו שהעבודה שאתם מבצעים בקריאות החוזרות האלה מוגבלת לביצוע עבודה שמובילה לעדכון בפועל של ממשק המשתמש. כל עבודה אחרת שלא נוגעת ב-DOM או מעדכנת סגנונות תעכב שלא לצורך את הרינדור של הפריים הבא, אז היזהרו!
סיכום
נתוני שטח הם מקור המידע הכי טוב שאפשר להסתמך עליו כדי להבין אילו אינטראקציות בעייתיות למשתמשים אמיתיים בשטח. כשמסתמכים על כלים לאיסוף נתונים בשטח, כמו ספריית JavaScript של web-vitals (או ספק RUM), אפשר להיות בטוחים יותר לגבי האינטראקציות הבעייתיות ביותר, ואז לעבור לשחזור של אינטראקציות בעייתיות במעבדה ולתקן אותן.