איך שליפה מראש (prefetch) עזרה ל-Terra להגדיל את שיעור הקליקים על המודעות ב-30% ולהאיץ את פעולת Largest Contentful Paint (LCP).

שליפה מראש (prefetch) של משאבים מאיצה את זמני הטעינה של הדפים ומשפרת את המדדים העסקיים.

Guilherme Moser de Souza
Guilherme Moser de Souza

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

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

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

אסטרטגיית שליפה מראש (prefetch)

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

  • חשיפה של קישורים למאמרים שנשלפו מראש: Terra השתמשה ב-Intersectionמיקום API כדי לזהות את הניראות של הקטע שמכיל את המאמרים שהם רצו לאחזר מראש.
  • תנאים מועדפים לשימוש מוגבר בחבילת הגלישה: כפי שצוין קודם, שליפה מראש (prefetch) היא שיפור ספקולטיבי בביצועים שצורך יותר נתונים, ויכול להיות שהוא לא יניב תוצאה רצויה בכל מצב. כדי לצמצם את הסבירות לבזבוז רוחב פס, מערכת Terra משתמשת ב-Network Information API וב-Device Memory API כדי לקבוע אם לאחזר את המאמר הבא. Terra מאחזרת את המאמר הבא רק כאשר:
    • מהירות החיבור היא 3G לפחות ולמכשיר יש זיכרון של 4GB לפחות.
    • או אם במכשיר פועלת מערכת iOS.
  • המעבד (CPU) לא פעיל: לבסוף, Terra בודקת אם המעבד (CPU) לא פעיל ויכול לבצע עבודה נוספת באמצעות requestIdleCallback, שמחזיר את העיבוד של קריאה חוזרת כשה-thread הראשי לא פעיל או לפי תאריך יעד ספציפי (אופציונלי) – המוקדם מביניהם.

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

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

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

ההשפעה על העסק

כדי למדוד את ההשפעה של השיטה הזו, Terra השיקה תחילה את התכונה הזו בקטע 'תוכן קשור' בדף המאמר. קוד מנטר התנועה של Urchin עזר להם להבחין בין מאמרים שנשלפו מראש לבין מאמרים שלא נשלפו מראש, לצורך השוואה. אחרי שבועיים של בדיקות A/B מוצלחות, ב-Tera החליטו להוסיף את הפונקציונליות של שליפה מראש לקטע 'מומלץ עבורך'.

כתוצאה משליפה מראש (prefetch) של מאמרים, ראינו עלייה כוללת במדדי המודעות וירידה בזמני ה-LCP ו-Time to First Byte (TTFB):

המדד נייד מחשב
שיעור הקליקים (CTR) של המודעות 11%+ +30%
ניראות המודעות +10.5% ‎+6%
LCP -51% -73%
TFC -83% -84%

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

פרטים טכניים

אפשר להשיג שליפה מראש (prefetch) באמצעות רמזים למשאבים כמו rel=prefetch או rel=preload, דרך ספריות כמו quicklink או Guess.js או באמצעות ה-API החדש יותר של Speculation Rules API. ב-Tera בחרו להטמיע את האפשרות הזו באמצעות API לשליפה עם עדיפות נמוכה בשילוב עם מופע של Intersection Reportinger. חברת Terra בחרה באפשרות הזו כי היא מאפשרת להם לתמוך ב-Safari, שעדיין לא תומך בשיטות אחרות לשליפה מראש כמו rel=prefetch או Speculation Rules API, ולא היה צורך בספריית JavaScript עם כל התכונות לצרכים של Terra.

ה-JavaScript שבהמשך דומה, פחות או יותר, לקוד שמשמש את Terra:

function prefetch(nodeLists) {
  // Exclude slow ECTs < 3g
  if (navigator.connection &&
    (navigator.connection.effectiveType === 'slow-2g'
      || navigator.connection.effectiveType === '2g')
  ) {
    return;
  }

  // Exclude low end device which is device with memory <= 2GB
  if (navigator.deviceMemory && navigator.deviceMemory <= 2) {
    return;
  }

  const fetchLinkList = {};

  const observer = new IntersectionObserver(function (entries) {
    entries.forEach(function (entry) {
      if (entry.isIntersecting) {
        if (!fetchLinkList[entry.target.href]) {
          fetchLinkList[entry.target.href] = true;

          fetch(entry.target, {
            priority: 'low'
          });
        }

        observer.unobserve(entry = entry.target);
      }
    });
  });
}

const idleCallback = window.requestIdleCallback || function (cb) {
  let start = Date.now();

  return setTimeout(function () {
    cb({
      didTimeout: false,
      timeRemaining: function () {
        return Math.max(0, 50 - (Date.now() - start));
      }
    });
  }, 1);
}

idleCallback(function () {
  prefetch(nodeLists)
})
  • הפונקציה prefetch בודקת קודם את איכות החיבור המינימלית ואת זיכרון המכשיר לפני הפעלת השליפה מראש.
  • לאחר מכן היא משתמשת ב-IntersectionObserver כדי לעקוב אחרי מקרים שבהם רכיבים הופכים לגלויים באזור התצוגה, ולאחר מכן היא מוסיפה כתובות URL לרשימה לשליפה מראש (prefetch).
  • תהליך השליפה מראש (prefetch) מתוזמן עם requestIdleCallback, במטרה להפעיל את הפונקציה prefetch כשה-thread הראשי לא פעיל.

סיכום

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

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