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

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

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

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

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

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

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

צוות 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, וגם על שיפור היכולות של DevTools כדי שיהיה קל יותר לזהות מקרים קיצוניים כאלה.

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

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

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

האתר לדוגמה כבר מהיר, אבל גם כך אפשר לראות איך רינדור מראש משפר את חוויית המשתמש. לכן, יכולה להיות לכך השפעה ישירה גם על מדדי הליבה של חוויית השימוש באינטרנט באתר, עם זמן 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.
  • Edge: ‏ 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 כדי לבצע ספקולציה כשמשתמשים מקיימים אינטראקציה עם קישורים.
  • כללים של ספקולציה שהוכנסו באופן דינמי: הכלל יכול להתבסס על לוגיקה של אפליקציה, להתאים אישית למשתמש או להתבסס על שיטות ניתוח חזוי אחרות.

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

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

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

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

  • Chrome: ‏ 121.
  • Edge: ‏ 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.

כללי השערות כבר תומכים בהאצה של טעינה מראש ממקורות שונים, אבל שוב, רק כשאין קובצי 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 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 DevTools כדי להוסיף את הרכיב <script type = "speculationrules"> לא רושמת את כללי השערת הקוד. במקום זאת, כדי להוסיף את הכללים ל-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 של הקצה הקדמי יכול לזהות דפים שעברו עיבוד מראש ולפעול בהתאם.

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

ניתוח נתונים משמש למדידת השימוש באתר. לדוגמה, אפשר להשתמש ב-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 מפתח באופן פעיל את האפשרות של עיבוד מראש, ויש לנו הרבה תוכניות להרחיב את ההיקף של מה שזמין בגרסה 108 של Chrome. נשמח לקבל מכם משוב במאגר GitHub או באמצעות כלי המעקב אחר בעיות שלנו. אנחנו גם מחכים לשמוע מכם על מקרים לדוגמה שבהם השתמשתם ב-API החדש והמרגש הזה, ונשמח לשתף אותם.

תודות

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