עיבוד מראש של דפים ב-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 Predictors'.

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

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

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

התכונה Typeahead בסרגל הכתובות של 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 Template 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 לא מעבד מסגרות iframe ממקורות שונים בדפים שעברו עיבוד מראש, עד להפעלה.

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

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

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

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

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

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

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

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

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

מקור

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

כותרת ה-HTTP Speculation-Rules מוחזרת עם המסמך ומפנה למיקום של קובץ 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 שבעזרתן אפשר להציג את ה-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.
  • קצה: 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.

כללי השערות כבר תומכים בהטמעה מראש של פריטים מ-origin שונה, אבל שוב, רק כשאין קובצי cookie לדומיין מ-origin שונה. אם יש קובצי 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 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"> שהוחדרו מגיבוב או מסקריפטים לא מעובדים. האפשרות הזו לא תומכת בכללים שכלולים ב-HTML הראשוני, לכן צריך להחדיר כללים באמצעות JavaScript לאתרים שמשתמשים ב-CSP מחמיר.

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

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

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

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

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

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

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

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 שמוצג בו הפעלה חיוביתStart (התחלה) כדי לציין שהדף עבר עיבוד מראש
בדיקת העיבוד מראש במסוף.

כשהמשתמש שצופה בדף מפעיל אותו, האירוע 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 של הדפדפן.

מדדי הליבה לבדיקת חוויית המשתמש באתר, שנמדדים על ידי 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