עיבוד מראש של דפים ב-Chrome לניווט מיידי בדפים

Barry Pollard
Barry Pollard

תמיכה בדפדפנים

  • Chrome: 109.
  • Edge: 109.
  • Firefox: לא נתמך.
  • Safari: לא נתמך.

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

היסטוריה קצרה של עיבוד מראש

בעבר, Chrome תמך בהצעה לשימוש במשאב <link rel="prerender" href="/next-page">, אבל לא הייתה תמיכה רחבה בה מחוץ ל-Chrome, והיא לא הייתה ממשק API יעיל במיוחד.

עיבוד מראש מהדור קודם באמצעות ההצעה rel=prerender בקישור הוצא משימוש לטובת NoState Prefetch, שבמקום זאת מאחזר את המשאבים הדרושים לדף העתידי, אבל לא מעבד מראש את הדף במלואו ולא מבצע JavaScript. השליפה מראש (prefetch) של NoState עוזרת לשפר את ביצועי הדפים על ידי שיפור טעינת המשאב, אבל לא מספקת טעינה מיידית של הדף כמו במצב של עיבוד מראש מלא.

צוות Chrome החזיר את האפשרות של עיבוד מראש מלא ל-Chrome. כדי למנוע סיבוכים בשימוש הקיים ולאפשר הרחבה עתידית של העיבוד מראש, המנגנון החדש לעיבוד מראש לא ישתמש בסינטקס <link rel="prerender"...>, שיישאר בתוקף לצורך אחסון מראש ללא מצב (NoState Prefetch), במטרה להוציא אותו משימוש בשלב כלשהו בעתיד.

איך מתבצע עיבוד מראש של דף?

ניתן לעבד מראש דף באחת מארבע דרכים, שכולן נועדו לזרז את הניווט:

  1. כשמקלידים כתובת URL בסרגל הכתובות של Chrome (שנקרא גם 'סרגל הכתובות'), דפדפן Chrome עשוי לבצע עיבוד מראש של הדף באופן אוטומטי, אם רמת הסמך גבוהה של כניסה לדף הזה, על סמך היסטוריית הגלישה הקודמת שלכם.
  2. כשמשתמשים בסרגל הסימניות, יכול להיות ש-Chrome יבצע עיבוד מראש של הדף באופן אוטומטי אם תחזיקו את הסמן מעל אחד מהלחצנים של הסימניות.
  3. כשמקלידים מונח חיפוש בסרגל הכתובות של Chrome, Chrome עשוי לבצע עיבוד מראש של דף תוצאות החיפוש באופן אוטומטי, אם מנוע החיפוש מורה לו לעשות זאת.
  4. אתרים יכולים להשתמש ב-Speculation Rules API כדי להורות ל-Chrome באופן פרוגרמטי אילו דפים לעיבוד מראש. האפשרות הזו מחליפה את הפעולה של <link rel="prerender"...> ומאפשרת לאתרים לבצע רינדור מראש של דף באופן יזום על סמך כללי ספקולציה בדף. הם יכולים להופיע בדפים באופן סטטי, או להוזן באופן דינמי על ידי JavaScript לפי שיקול דעתו של בעלי הדף.

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

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

ההשפעה של העיבוד מראש

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

דוגמה להשפעה של עיבוד מראש.

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

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

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

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

הצגת התחזיות של סרגל הכתובות ב-Chrome

בתרחיש לדוגמה הראשון, אפשר לראות את התחזיות של Chrome לכתובות URL בדף chrome://predictors:

הדף &#39;תחזיות ב-Chrome&#39; מסונן כך שיו��גו בו תחזיות נמוכות (אפור), בינוניות (כתום) וגבוהות (ירוק) על סמך הטקסט שהוזן.
הדף 'תחזיות ב-Chrome'.

קווים ירוקים מציינים שהמערכת בטוחה מספיק כדי להפעיל עיבוד מראש. בדוגמה הזו, הקלדה של 's' מספקת רמת ביטחון סבירה (כתום), אבל אחרי הקלדה של 'sh', ל-Chrome יש מספיק ביטחון שכמעט תמיד מנווטים אל https://sheets.google.com.

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

הגורמים האלה גם קובעים את האפשרויות המוצעות בסרגל הכתובות, שאולי שמתם לב אליהן:

התכונה &#39;השלמה אוטומטית&#39; בסרגל הכתובות של Chrome
התכונה 'השלמה אוטומטית' בסרגל הכתובות

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

  • ברמת ביטחון של יותר מ-50% (מוצגת בכתום), Chrome מתחבר מראש לדומיין באופן יזום, אבל לא מבצע עיבוד מראש של הדף.
  • אם רמת האמון גבוהה מ-80% (מוצגת בירוק), Chrome יבצע עיבוד מראש של כתובת ה-URL.

Speculation Rules API

באפשרות של עיבוד מראש של Speculation Rules API, מפתחי אתרים יכולים להוסיף לדפים שלהם הוראות JSON כדי להודיע לדפדפן אילו כתובות URL צריך לעבד מראש:

<script type="speculationrules">
{
  "prerender": [
    {
      "urls": ["next.html", "next2.html"]
    }
  ]
}
</script>

לחלופין, באמצעות כללי מסמך (זמינים מ-Chrome 121 ואילך), שמבצעים עיבוד מראש של קישורים שנמצאים במסמך על סמך סלקטורים של href (על סמך URL Pattern API) או סלקטורים של CSS:

<script type="speculationrules">
{
  "prerender": [{
    "where": {
      "and": [
        { "href_matches": "/*" },
        { "not": {"href_matches": "/wp-admin"}},
        { "not": {"href_matches": "/*\\?*(^|&)add-to-cart=*"}},
        { "not": {"selector_matches": ".do-not-prerender"}},
        { "not": {"selector_matches": "[rel~=nofollow]"}}
      ]
    }
  }]
}
</script>

צוות Chrome הכין Codelab של כללי ספקולציות שידריך אתכם איך להוסיף כללי ספקולציות לאתר.

תשוקה

תמיכה בדפדפן

  • Chrome: 121.
  • קצה: 121.
  • Firefox: לא נתמך.
  • Safari: לא נתמך.

ההגדרה eagerness משמשת לציון מתי ההשערות צריכות להתרחש, והיא שימושית במיוחד לכללי מסמכים:

  • immediate: הערך הזה משמש לביצוע ספקולציות בהקדם האפשרי, כלומר ברגע שכללי הספקולציות מתקיימים.
  • eager: ההתנהגות הזו זהה להגדרה של immediate, אבל בעתיד אנחנו מעוניינים למקם אותה במקום כלשהו בין immediate ל-moderate.
  • moderate: הפעולה הזו מבצעת ספקולציות אם מעבירים את הסמן מעל לקישור למשך 200 אלפיות השנייה (או באירוע pointerdown אם מוקדם יותר, ובנייד כאשר לא קיים אירוע hover).
  • conservative: מתבצעת השערה לגבי מצביע או נגיעה למטה.

ערך ברירת המחדל של eagerness לכללי list הוא immediate. אפשר להשתמש באפשרויות moderate ו-conservative כדי להגביל את הכללים של list לכתובות URL שהמשתמש יוצר איתן אינטראקציה, לרשימת כתובות ספציפית. עם זאת, במקרים רבים עדיף להשתמש בכללי document עם תנאי where מתאים.

ערך ברירת המחדל של eagerness לכללי document הוא conservative. מסמך יכול להכיל הרבה כתובות URL, לכן צריך להשתמש ב-immediate או ב-eager לכלל document בזהירות (ראו גם את הקטע הגבלות ב-Chrome שבהמשך).

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

האפשרות moderate היא דרך ביניים, ואתרים רבים יכולים להפיק תועלת מכלל ההשערה הבא, שיגרום לעיבוד מראש של קישור כשמקיש��ם עליו עם הסמן למשך 200 אלפיות השנייה או באירוע pointerdown, כדרך בסיסית אך יעילה לה��מ��ת ��ללי ה��ערה:

<script type="speculationrules">
{
  "prerender": [{
    "where": {
      "href_matches": "/*"
    },
    "eagerness": "moderate"
  }]
}
</script>

שליפה מראש (prefetch)

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

<script type="speculationrules">
{
  "prefetch": [
    {
      "urls": ["next.html", "next2.html"]
    }
  ]
}
</script>

מגבלות ב-Chrome

ב-Chrome יש מגבלות כדי למנוע שימוש יתר ב-Speculation Rules API:

התלהבות שליפה מראש (prefetch) עיבוד מראש
immediate / eager 50 10
moderate / conservative 2 (FIFO) 2 (FIFO)
הגבלות על השערות ב-Chrome

ההגדרות moderate ו-conservative – שתלויות באינטראקציה של המשתמש – פועלות לפי הכלל 'ראשון נכנס, ראשון יוצא' (FIFO): אחרי שמגיעים למגבלה, השערה חדשה תגרום לביטול של השערה הי��נה ביותר ולהחלפתה בשערה החדשה, כדי לחסוך בזיכרון. אפשר להפעיל מחדש השערה שבוטלה – לדוגמה, על ידי החזקת העכבר מעל הקישור הזה שוב – וכתוצאה מכך תתבצע השערה מחדש לגבי כתובת ה-URL הזו, וההשערה הישנה ביותר תוחלף בה. במקרה כזה, ההשערה הקודמת תשמור במטמון את כל המשאבים שאפשר לשמור במטמון במטמון ה-HTTP של כתובת ה-URL הזו, ��ך שהעלות של ביצוע השערה נוספת אמורה להיות נמוכה יותר. זו הסיבה לכך שהמגבלה היא מ-2 ומעלה. כללי רשימות סטטיות לא מופעלים על ידי פעולת משתמש, ולכן יש להם מגבלה גבוהה יותר כי אין לדפדפן אפשרות לדעת אילו כללים נדרשים ומתי הם נדרשים.

המגבלות של immediate ו-eager הן גם דינמיות, כך שהסרת רכיב סקריפט של כתובת URL מסוג list תיצור קיבולת על ידי ביטול ההשערות שהוסרו.

בנוסף, Chrome ימנע שימוש בשערות בתנאים מסוימים, כולל:

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

בנוסף, Chrome לא מבצע עיבוד של iframes ממקורות שונים בדפים שעברו עיבוד מראש עד להפעלה.

כל התנאים האלה נועדו לצמצם את ההשפעה של ספקולציות מוגזמות כשהן מזיקות למשתמשים.

איך מוסיפים לדף כללי ספקולציות

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

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

אם אתם מעדיפים הטמעה דינמית על סמך פעולות כמו החזקת העכבר מעל קישור או לחיצה עליו, כפי שספריות רבות עשו בעבר באמצעות <link rel=prefetch>, מומלץ לבדוק את כללי המסמך, כי הם מאפשרים לדפדפן לטפל ברבים מתרחישי השימוש שלכם.

אפשר להוסיף כללי ספקולציה ב-<head> או ב-<body> שבמסגרת הראשית. לא מתבצעת פעולה לפי כללי השערות בפריימים משניים, וכ��לי השערות בדפים שעברו עיבוד מראש מופעלים רק אחרי שהדף מופעל.

כותרת ה-HTTP‏ Speculation-Rules

תמיכה בדפדפנים

  • Chrome:‏ 121.
  • קצה: 121.
  • Firefox: לא נתמך.
  • Safari: לא נתמך.

מקור

אפשר להעביר כללי ספקולציות גם באמצעות כותרת HTTP Speculation-Rules במקום לכלול אותם ישירות ב-HTML של המסמך. כך מתאפשרת פריסה קלה יותר על ידי רשתות CDN ללא צורך לשנות את תוכן המסמך בעצמם.

הכותרת Speculation-Rules של HTTP מוחזרת עם המסמך ומצביעה על מיקום של קובץ JSON שמכיל את כללי השערות העסקיות:

Speculation-Rules: "/speculationrules.json"

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

Content-Type: application/speculationrules+json
Access-Control-Allow-Origin: *

אם רוצים להשתמש בכתובות URL יחסיות, מומלץ לכלול את המפתח "relative_to": "document" בכללי השערות. אחרת, כתובות ה-URL היחסיות יהיו יחסיות לכתובת ה-URL של קובץ ה-JSON של כללי הספקולציות. האפשרות הזו שימושית במיוחד אם צריך לבחור חלק מהקישורים מאותו מקור או את כולם.

כללי ספקולציות והסכמי SPA

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

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

כללי ספקולציות לניפוי באגים

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

מספר כללי ספקולציות

אפשר גם להוסיף כמה כללי ספקולציה לאותו דף, והם יתווספו לכללים הקיימים. לכן, כל הדרכים הבאות גורמות לעיבוד מראש של one.html וגם של two.html:

רשימה של כתובות URL:

<script type="speculationrules">
{
  "prerender": [
    {
      "urls": ["one.html", "two.html"]
    }
  ]
}
</script>

כמה סקריפטים של speculationrules:

<script type="speculationrules">
{
  "prerender": [
    {
      "urls": ["one.html"]
    }
  ]
}
</script>
<script type="speculationrules">
{
  "prerender": [
    {
      "urls": ["two.html"]
    }
  ]
}
</script>

רשימות מרובות בתוך קבוצה אחת של speculationrules

<script type="speculationrules">
{
  "prerender": [
    {
      "urls": ["one.html"]
    },
    {
      "urls": ["two.html"]
    }
  ]
}
</script>

תמיכה בדפדפנים

  • Chrome:‏ 121.
  • Edge:‏ 121.
  • Firefox: לא נתמך.
  • Safari: לא נתמך.

מקור

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

לדוגמה, פרמטרים של UTM משמשים את Google Analytics למדידת קמפיינים, אבל בדרך כלל הם לא גורמים להעברה של דפים שונים מהשרת. המשמעות היא ש-page1.html?utm_content=123 ו-page1.html?utm_content=456 יציגו את אותו דף מהשרת, כך שאפשר יהיה לעשות שימוש חוזר באותו דף מהמטמון.

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

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

כללי השערות תומכים בשימוש ב-expects_no_vary_search כדי לציין איפה צפויה להוחזר כותרת HTTP מסוג No-Vary-Search. כך תוכלו להימנע מהורדות מיותרות.

<script type="speculationrules">
{
  "prefetch": [{
    "urls": ["/products*"],
    "expects_no_vary_search": "params=(\"id\")"
  }]
}
</script>

<a href="/products?id=123">Product 123</a>
<a href="/products?id=124">Product 124</a>

בדוגמה הזו, ה-HTML של הדף הראשוני /products זהה למזהי המוצרים 123 ו-124. עם זאת, תוכן הדף ישתנה בסופו של דבר על סמך עיבוד בצד הלקוח באמצעות JavaScript כדי לאחזר נתוני מוצרים באמצעות פרמטר החיפוש id. לכן אנחנו מבצעים אחסון מקדים של כתובת ה-URL הזו, והיא אמורה להחזיר כותרת HTTP מסוג No-Vary-Search שמציינת שאפשר להשתמש בדף לכל פרמטר חיפוש מסוג id.

עם זאת, אם המשתמש לוחץ על אחד מהקישורים לפני השלמת האחזור מראש, יכול להיות שהדפדפן לא קיבל את הדף /products. במקרה כזה, הדפדפן לא יודע אם הוא יכיל את כותרת ה-HTTP No-Vary-Search. לאחר מכן, הדפדפן יכול לבחור אם לאחזר את הקישור שוב או להמתין להשלמת האחזור מראש כדי לבדוק אם הוא מכיל כותרת HTTP מסוג No-Vary-Search. ההגדרה expects_no_vary_search מאפשרת לדפדפן לדעת שתגובת הדף צפויה לכלול כותרת HTTP מסוג No-Vary-Search, ולהמתין להשלמת האחזור מראש.

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

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

כברירת מחדל, השערות מוגבלות לדפים מאותו מקור. ניחושים לגבי דפים באותו אתר ממקורות שונים (לדוגמה, https://a.example.com יכול לבצע עיבוד מראש של דף ב-https://b.example.com). כדי להשתמש באפשרות הזו, הדף שבו מתבצע הניחוש (https://b.example.com בדוגמה הזו) צריך להביע הסכמה על ידי הכללת כותרת HTTP מסוג Supports-Loading-Mode: credentialed-prerender, אחרת Chrome יבטל את הניחוש.

יכול להיות שגרסאות עתידיות גם יאפשרו עיבוד מראש לדפים באתרים שונים ולדפים שונים ממקורות שונים, כל עוד לא קיימים קובצי cookie לדף שעבר עיבוד מראש ובדף שעבר עיבוד מראש מוגדר זאת עם כותרת HTTP דומה מסוג Supports-Loading-Mode: uncredentialed-prerender.

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

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

<script type="speculationrules">
  {
    "prerender": [
      {
        "where": { "href_matches": "/*" },
        "eagerness": "moderate"
      }
    ],
    "prefetch": [
      {
        "where": { "not": { "href_matches": "/*" } },
        "eagerness": "moderate"
      }
    ]
  }
</script>

כברירת מחדל, ההגבלה שמונעת ספקולציות בין מקורות לקישורים ממקורות שונים נדרשת מטעמי אבטחה. זוהי שיפור לעומת <link rel="prefetch"> ליעדים ממקורות שונים, שלא ישלחו גם הם קובצי cookie אבל עדיין ינסו לבצע אחסון מקדים. הניסיון הזה יוביל לאחסון מקדים מיותר שצריך לשלוח מחדש, או גרוע מכך, לטעינה שגויה של הדף.

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

זיהוי תמיכה ב-API של כללי ספקולציות

אפשר לזהות את התמיכה ב-Speculation Rules API באמצעות בדיקות HTML רגילות:

if (HTMLScriptElement.supports && HTMLScriptElement.supports('speculationrules')) {
  console.log('Your browser supports the Speculation Rules API.');
}

הוספה של כללי ספקולציות באופן דינמי באמצעות JavaScript

זוהי דוגמה להוספת כלל של ספקולציות prerender באמצעות JavaScript:

if (HTMLScriptElement.supports &&
    HTMLScriptElement.supports('speculationrules')) {
  const specScript = document.createElement('script');
  specScript.type = 'speculationrules';
  specRules = {
    prerender: [
      {
        urls: ['/next.html'],
      },
    ],
  };
  specScript.textContent = JSON.stringify(specRules);
  console.log('added speculation rules to: next.html');
  document.body.append(specScript);
}

בדף הדגמה הזה אפשר לראות הדגמה של עיבוד מראש של Speculation Rules API באמצעות הטמעת JavaScript.

הוספת רכיב <script type = "speculationrules"> ישירות ל-DOM באמצעות innerHTML לא תירשם את כללי השערות מטעמי אבטחה, וצריך להוסיף אותם כפי שצוין למעלה. עם זאת, תוכן שנוסף באופן דינמי באמצעות innerHTML שמכיל קישורים חדשים ייאספו בהתאם לכללים הקיימים בדף.

באופן דומה, עריכה ישירה של החלונית Elements בכלי הפיתוח ל-Chrome לצורך הוספת הרכיב <script type = "speculationrules"> לא רושמת את כללי ההשערה. במקום זאת, צריך להריץ את הסקריפט שיוסיף את ה-DOM באופן דינמי ל-DOM כדי להוסיף את הכללים. במקום זאת, צריך להריץ את הסקריפט שיוסיף את הכללים באופן דינמי.

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

כדי להוסיף כללי ספקולציה באמצעות מערכת ניהול תגים כמו Google Tag Manager ‏(GTM), צריך להוסיף אותם באמצעות JavaScript, ולא להוסיף את הרכיב <script type = "speculationrules"> ישירות דרך GTM, מהסיבות שצוינו למעלה:

הגדרת תג HTML בהתאמה אישית ב-Google Tag Manager
הוספת כללי ספקולציה דרך Google Tag Manager

הערה: בדוגמה הזו נעשה שימוש ב-var כי אין תמיכה ב-const ב-GTM.

ביטול כללי ספקולציות

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

כללי ספקולציה ומדיניות Content Security Policy

כללי השערות משתמשים ברכיב <script>, גם אם הם מכילים רק JSON. לכן, אם האתר משתמש ב-script-src Content-Security-Policy, צריך לכלול את הכללים האלה ב-script-src – באמצעות גיבוב או nonce.

אפשר להוסיף inline-speculation-rules חדש ל-script-src כדי לאפשר תמיכה ברכיבי <script type="speculationrules"> שהוחדרו מסקריפטים עם גיבוב או עם nonce. התכונה הזו לא תומכת בכללים שכלולים ב-HTML הראשוני, לכן צריך להחדיר את הכללים ל-JavaScript באתרים שמשתמשים ב-CSP מחמירה.

זיהוי והשבתה של עיבוד מראש

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

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

הפעלה והשבתה של עיבוד מראש ב-Chrome

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

זיהוי והשבתה של העיבוד מראש בצד השרת

דפים שעברו עיבוד מראש יישלחו עם הכותרת Sec-Purpose ב-HTTP:

Sec-Purpose: prefetch;prerender

בדפים שאוחסנו מראש באמצעות Speculation Rules API, הכותרת הזו תוגדר רק ל-prefetch:

Sec-Purpose: prefetch

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

אם אתם לא רוצים שדף מסוים ייוצר מראש, הדרך הטובה ביותר לוודא שזה לא יקרה היא להחזיר קוד תגובה שאינו 2XX (כמו 503). עם זאת, כדי לספק את החוויה הטובה ביותר, מומלץ לאפשר עיבוד מראש במקום זאת, אבל לעכב פעולות שאמורות להתרחש רק כאשר הדף נצפה בפועל באמצעות JavaScript.

זיהוי עיבוד מראש ב-JavaScript

ה-API של document.prerendering ��חזיר true במהלך העיבוד מראש של הדף. דפים יכולים להשתמש באפשרות הזו כדי למנוע או לעכב פעילויות מסוימות במהלך העיבוד מראש, עד שהדף יופעל בפועל.

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

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

function pagePrerendered() {
  return (
    document.prerendering ||
    self.performance?.getEntriesByType?.('navigation')[0]?.activationStart > 0
  );
}

הדרך הקלה ביותר לבדוק אם דף עבר עיבוד מראש (במלואו או באופן חלקי) היא לפתוח את כלי הפיתוח אחרי שהדף מופעל ולהקליד performance.getEntriesByType('navigation')[0].activationStart במסוף. אם מוחזר ערך שאינו אפס, סימן שהדף עבר עיבוד מראש:

מסוף ב-Chrome DevTools שמוצגת בו הודעה חיובית על activationStart, שמציינת שהדף עבר עיבוד מראש
בדיקת עיבוד מראש במסוף.

כשהמשתמש שצופה בדף מפעיל אותו, האירוע prerenderingchange יישלח ב-document. לאחר מכן אפשר להשתמש בו כדי להפעיל פעילויות שבעבר היו מתחילות כברירת מחדל בטעינת הדף, אבל אתם רוצים לעכב אותן עד שהמשתמש יתחיל לצפות בדף בפועל.

באמצעות ממשקי ה-API האלה, JavaScript של הקצה הקדמי יכול לזהות דפים שעברו עיבוד מראש ולפעול בהתאם.

ההשפעה על ניתוח הנתונים

מערכת Analytics משמשת למדידת השימוש באתר, למשל לצורך מדידת צפיות בדפים ואירועים ב-Google Analytics. לחלופין, אפשר למדוד את מדדי הביצועים של הדפים באמצעות מעקב אחר משתמשים אמיתיים (RUM).

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

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

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

// Set up a promise for when the page is activated,
// which is needed for prerendered pages.
const whenActivated = new Promise((resolve) => {
  if (document.prerendering) {
    document.addEventListener('prerenderingchange', resolve, {once: true});
  } else {
    resolve();
  }
});

async function initAnalytics() {
  await whenActivated;
  // Initialise your analytics
}

initAnalytics();

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

// Set up a promise for when the page is first made visible
const whenFirstVisible = new Promise((resolve) => {
  if (document.hidden) {
    document.addEventListener('visibilitychange', resolve, {once: true});
  } else {
    resolve();
  }
});

async function initAnalytics() {
  await whenFirstVisible;
  // Initialise your analytics
}

initAnalytics();

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

השהיה של תוכן אחר במהלך העיבוד המקדים

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

לדוגמה, בהתאם לסקריפט הזה:

<script src="https://example.com/app/script.js" async></script>

אפשר לשנות את זה לרכיב סקריפט שמוטמע באופן דינמי, שמוטמע רק על סמך פונקציית whenActivated הקודמת:

async function addScript(scriptUrl) {
  await whenActivated;
  const script = document.createElement('script');
  script.src = 'scriptUrl';
  document.body.appendChild(script);
}

addScript('https://example.com/app/script.js');

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

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

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

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

מדידת ביצועים

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

המדדים הבסיסיים של חוויית המשתמש (Core Web Vitals) נמדדים על ידי Chrome דרך הדוח לגבי חוויית המשתמש ב-Chrome, והם נועדו למדוד את חוויית המשתמש. לכן, המדדים האלה נמדדים על סמך זמן ההפעלה. לרוב, הפעולה הזו תוביל ל-LCP של 0 שניות, מה שמראה שזו דרך מצוינת לשפר את המדדים הבסיסיים של חוויית המשתמש.

מגרסה 3.1.0, הספרייה web-vitals עודכנה כדי לטפל בניווטים שעברו עיבוד מראש באותו אופן שבו Chrome מודד את מדדי Core Web Vitals. הגרסה הזו גם מסמנת ניווטים שעברו עיבוד מראש למדדים האלה במאפיין Metric.navigationType אם הדף עבר עיבוד מראש באופן מלא או חלקי.

מדידה של עיבודים מראש

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

// Set Custom Dimension for Prerender status
gtag('set', { 'dimension1': pagePrerendered() });
// Initialise GA - including sending page view by default
gtag('config', 'G-12345678-1');

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

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

מדידת שיעורי ההיטים

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

כדי למדוד את הנתון הזה, אפשר להפעיל אירוע ניתוח נתונים כשכללים של השערות מוכנסים – אחרי בדיקה שהדפדפן תומך ברינדור מראש באמצעות HTMLScriptElement.supports('speculationrules') – כדי לציין שהתבצעה בקשה לרינדור מראש. (הערה: העובדה שעיבוד מראש התבקש לא מעידה על כך שהוא התחיל או הושלם. כפי שצוין קודם, עיבוד מראש הוא רמז לדפדפן, והוא עשוי לבחור לא לעבד מראש דפים על סמך הגדרות המשתמש, השימוש הנוכחי בזיכרון או שיטות ניתוח נתונים אחרות).

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

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

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

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

ההשפעה על תוספים

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

משוב

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

אישורים

תמונה ממוזערת של Marc-Olivier Jodoin ב-Unsplash