ניסוי במדידת ניווטים רכים

מאז ההשקה, התוכנית של מדדי הליבה לבדיקת חוויית המשתמש באתר נועדה למדוד את חוויית המשתמש בפועל באתר, ולא את הפרטים הטכניים שמאחורי האופן שבו האתר נוצר או נטען. שלושת המדדים של Core Web Vitals נוצרו כמדדים שמתמקדים במשתמשים – התפתחות של מדדים טכניים קיימים כמו DOMContentLoaded או load, שמדדו זמני אירועים שלרוב לא היו קשורים לאופן שבו המשתמשים חשו לגבי ביצועי הדף. לכן, הטכנולוגיה שבה נעשה שימוש כדי ליצור את האתר לא אמורה להשפיע על הדירוג, בתנאי שהאתר מניב ביצועים טובים.

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

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

צוות Chrome מתייחס לאתגר הזה כבר זמן מה, ומנסה להגיע להגדרה סטנדרטית של 'ניווט רך' ולדרכים למדוד את מדדי Core Web Vitals במקרים כאלה – באופן דומה למדידת אתרים שמוטמעים בארכיטקטורה הרגילה של כמה דפים (MPA). אנחנו עדיין בשלבים מוקדמים, אבל הצוות מוכן עכשיו להרחיב את הגישה לתכונות שכבר הטמענו, כדי שאתרים יוכלו להתנסות בהן. כך בעלי האתרים יוכלו לספק משוב על הגישה עד כה.

מהי ניווט רך?

לשם כך הכנו את ההגדרה הבאה לניווט רך:

  • הניווט מופעל על ידי פעולה של משתמש.
  • הניווט גורם לשינוי בכתובת ה-URL שגלויה למשתמש ולשינוי בהיסטוריה.
  • הניווט גורם לשינוי ב-DOM.

באתרים מסוימים, שיטות הניתוח האלה עשויות להוביל לתוצאות חיוביות שגויות (משתמשים לא יראו ש'ניווט' התרחש בפועל) או לתוצאות שליליות שגויות (המשתמש רואה ש'ניווט' התרחש למרות שלא מתקיימים הקריטריונים האלה). נשמח לקבל משוב על שיטות הניתוח במאגר המפרטים של הניווט הרך.

איך Chrome מטמיע ניווט רך?

אחרי שהאלגוריתמים ההיורסטיים של הניווט הרך יופעלו (מידע נוסף מופיע בקטע הבא), האופן שבו Chrome מדווח על מדדי ביצועים מסוימים ישתנה:

  • אירוע soft-navigation PerformanceTiming יופיע אחרי כל זיהוי של ניווט רך.
  • Performance API יספק גישה לרשומת תזמון soft-navigation, כפי שהיא נשלחת על ידי האירוע soft-navigation PerformanceTiming.
  • המדדים First Paint (FP)‏, First Contentful Paint (FCP) ו-Largest Contentful Paint (LCP) יותאמו מחדש ויופקו מחדש בהפעלות הבאות שלהם. (הערה: התכונות FP ו-FCP לא מוטמעות).
  • המאפיין navigationId יתווסף לכל אחד מהזמנים של ביצועים (first-paint,‏ first-contentful-paint,‏ largest-contentful-paint,‏ first-input-delay,‏ event ו-layout-shift) שתואם לרשומה של הניווט שהאירוע היה קשור אליה, כדי לאפשר חישוב של הזזה מצטברת של הפריסה (CLS) ושל אינטראקציה עד לציור הבא (INP).

השינויים האלה יאפשרו למדדים הבסיסיים של חוויית המשתמש (Core Web Vitals) – וחלק מהמדדים האבחוניים המשויכים – להימדד לכל ניווט בדף, אבל יש כמה ניואנסים שצריך להביא בחשבון.

מהן ההשלכות של הפעלת ניווט רך ב-Chrome?

ריכזנו כאן כמה מהשינויים שבעלי אתרים צריכים להביא בחשבון אחרי הפעלת התכונה הזו:

  • יכול להיות שאירועי FP,‏ FCP ו-LCP נוספים יועברו מחדש עבור ניווטים רכים. הדוח לגבי חוויית המשתמש ב-Chrome‏ (CrUX) יתעלם מהערכים הנוספים האלה, אבל הדבר עשוי להשפיע על כל מעקב אחר מדידת משתמשים אמיתיים (RUM) באתר. אם יש לכם חששות לגבי ההשפעה של השינוי הזה על המדידות האלה, כדאי לפנות לספק ה-RUM. בקטע בנושא מדידת מדדי הליבה לבדיקת חוויית המשתמש (Core Web Vitals) לניווטים חלקים
  • יכול להיות שתצטרכו להביא בחשבון את המאפיין החדש (והאופציונלי) navigationID ברשומות הביצועים שלכם בקוד האפליקציה באמצעות הרשומות האלה.
  • רק דפדפנים המבוססים על Chromium יתמכו במצב החדש הזה. רבים מהמדדים החדשים ביותר זמינים רק בדפדפנים המבוססים על Chromium, אבל חלקם (FCP, LCP) זמינים בדפדפנים אחרים, ולא כולם שדרגו לגרסה העדכנית ביותר של הדפדפנים שמבוססים על Chromium. לכן, חשוב לזכור שחלק מהמשתמשים לא ידווחו על מדדי ניווט רך.
  • זוהי תכונה חדשה וניסיונית שלא מופעלת כברירת מחדל, ולכן בעלי אתרים צריכים לבדוק אותה כדי לוודא שאין לה השפעות לוואי לא רצויות.

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

איך מפעילים ניווט רך ב-Chrome?

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

מפתחים יכולים להפעיל את התכונה הזו על ידי הפעלת הדגל תכונות ניסיוניות של פלטפורמת האינטרנט בקובץ chrome://flags/#enable-experimental-web-platform-features, או באמצעות הארגומנט --enable-experimental-web-platform-features בשורת הפקודה כשמפעילים את Chrome.

איך אפשר למדוד ניווטים רכים?

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

דיווח על ניווטים רכים

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

const observer = new PerformanceObserver(console.log);
observer.observe({ type: "soft-navigation", buffered: true });

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

דיווח על המדדים לגבי כתובת ה-URL המתאימה

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

אפשר להשתמש במאפיין navigationId של PerformanceEntry המתאים כדי לקשר את האירוע לכתובת ה-URL הנכונה. אפשר לחפש את המידע הזה באמצעות PerformanceEntry API:

const softNavEntry =
  performance.getEntriesByType('soft-navigation').filter(
    (entry) => entry.navigationId === navigationId
  )[0];
const hardNavEntry = performance.getEntriesByType('navigation')[0];
const navEntry = softNavEntry || hardNavEntry;
const pageUrl = navEntry?.name;

צריך להשתמש ב-pageUrl הזה כדי לדווח על המדדים בכתובת ה-URL הנכונה, ולא בכתובת ה-URL הנוכחית שבה הם השתמשו בעבר.

אחזור startTime של ניווטים רכים

ניתן לקבל את שעת ההתחלה של הניווט באופן דומה:

const softNavEntry =
  performance.getEntriesByType('soft-navigation').filter(
    (entry) => entry.navigationId === navigationId
  )[0];
const hardNavEntry = performance.getEntriesByType('navigation')[0];
const navEntry = softNavEntry || hardNavEntry;
const startTime = navEntry?.startTime;

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

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

מדידת מדדי Core Web Vitals לכל ניווט רך

כדי לכלול רשומות של מדדי ניווט רך, צריך לכלול את includeSoftNavigationObservations: true בקריאה observe של צופה הביצועים.

new PerformanceObserver((entryList) => {
  for (const entry of entryList.getEntries()) {
    console.log('Layout Shift time:', entry);
  }
}).observe({type: 'layout-shift', buffered: true, includeSoftNavigationObservations: true});

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

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

new PerformanceObserver((entryList) => {
  for (const entry of entryList.getEntries()) {
    const softNavEntry =
      performance.getEntriesByType('soft-navigation').filter(
        (navEntry) => navEntry.navigationId === entry.navigationId
      )[0];
    const hardNavEntry = performance.getEntriesByType('navigation')[0];
    const navEntry = softNavEntry || hardNavEntry;
    const startTime = navEntry?.startTime;
    console.log('LCP time:', entry.startTime - startTime);
  }
}).observe({type: 'largest-contentful-paint', buffered: true, includeSoftNavigationObservations: true});

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

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

איך צריך לטפל בתוכן שנשאר ללא שינוי בין ניווטים?

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

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

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

איך מודדים את זמן אחזור הבקשה (TTFB)?

הזמן עד בייט התגובה הראשון (TTFB) לטעינת דף רגילה מייצג את הזמן שבו החזירו את הבייטים הראשונים של הבקשה המקורית.

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

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

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

איך מודדים גם ישן וגם חדש?

במהלך הניסוי הזה, מומלץ להמשיך למדוד את מדדי הליבה לבדיקת חוויית המשתמש באתר באופן הנוכחי, על סמך ניווטים 'קשה' בדפים, בהתאם למה ש-CrUX ימדוד וידווח עליו כמערך הנתונים הרשמי של יוזמת Core Web Vitals.

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

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

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

הדרך הקלה ביותר להביא בחשבון את כל הניואנסים היא להשתמש בספריית ה-JavaScript web-vitals, שכוללת תמיכה ניסיונית בניווטים קלים נפרד soft-navs branch (שזמין גם ב-npm וב-unpkg). אפשר למדוד את זה באופן הבא (מחליפים את doTraditionalProcessing ו-doSoftNavProcessing לפי הצורך):

import {
  onTTFB,
  onFCP,
  onLCP,
  onCLS,
  onINP,
} from 'https://unpkg.com/web-vitals@soft-navs/dist/web-vitals.js?module';

onTTFB(doTraditionalProcessing);
onFCP(doTraditionalProcessing);
onLCP(doTraditionalProcessing);
onCLS(doTraditionalProcessing);
onINP(doTraditionalProcessing);

onTTFB(doSoftNavProcessing, {reportSoftNavs: true});
onFCP(doSoftNavProcessing, {reportSoftNavs: true});
onLCP(doSoftNavProcessing, {reportSoftNavs: true});
onCLS(doSoftNavProcessing, {reportSoftNavs: true});
onINP(doSoftNavProcessing, {reportSoftNavs: true});

מוודאים שהמדדים מדווחים לגבי כתובת ה-URL הנכונה כפי שצוין למעלה.

הספרייה web-vitals מדווחת על המדדים הבאים לגבי ניווטים עם יכולת שחזור:

מדד פרטים
החזרות מקדמות המערכת מדווחת על 0.
FCP המערכת מדווחת רק על ה-FCP הראשון בדף.
LCP הזמן של רכיב התוכן הבא הכי גדול (LCP) ביחס לזמן התחלת הניווט הרך. המערכת לא מביאה בחשבון צבעים קיימים שנוצרו מהניווט הקודם. לכן, הערך של LCP יהיה >= 0. כדרכו, הדיווח על כך יתבצע לאחר אינטראקציה או כשהדף יועבר לרקע, כי רק אז ניתן לסיים את הבדיקה של LCP.
CLS חלון המעבר הגדול ביותר בין זמני הניווט. כמו תמיד, זה קורה כשהדף עובר לרקע, כי רק אז אפשר לסיים את חישוב ה-CLS. המערכת מדווחת על ערך 0 אם אין שינויים.
INP ה-INP בין זמני הניווט. כדרכו, הדיווח על כך יתבצע לאחר אינטראקציה או כאשר הדף יועבר לרקע, כי רק אז ניתן לסיים את הדיווח על INP. לא יתבצע דיווח על ערך של 0 אם אין אינטראקציות.

האם השינויים האלה ייכללו במדידות של מדדי הליבה לבדיקת חוויית המשתמש באתר?

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

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

איך יתבצע הדיווח על ניווטים עם יכולת שחזור ב-CrUX?

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

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

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

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

משוב

אנחנו מבקשים מכם לשלוח לנו משוב על הניסוי הזה במקומות הבאים:

יומן שינויים

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

סיכום

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

תודות

תמונה ממוזערת של ג'ורדן מדריד בביטול הפתיחה