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

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

Guilherme Moser de Souza
Guilherme Moser de Souza

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

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

בניתוח המקרה הזה מתוארת ההטמעה של Terra, שהובילה לעלייה של 11% בשיעור הקליקים (CTR) על מודעות בנייד, לעלייה של 30% בשיעור הקליקים על מודעות במחשב ולירידה של 50% בזמני Largest Contentful Paint‏ (LCP).

אסטרטגיית אחזור מראש

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

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

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

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

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

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

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

כתוצאה מהשליפה מראש של מאמרים, נצפתה עלייה כללית במדדי המודעות וירידה בזמני LCP ו-זמן אחזור הבאיט הראשון (TTFB):

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

אם משתמשים בטעינה מראש (Pre-fetch) בזהירות, היא משפרת באופן משמעותי את זמן הטעינה של הדף, משפרת את מדדי המודעות ומקצרת את זמן ה-LCP.

פרטים טכניים

אפשר לבצע אחזור מראש באמצעות רמזים למשאבים כמו rel=prefetch או rel=preload, דרך ספריות כמו quicklink או Guess.js, או באמצעות Speculation Rules API החדש יותר. ב-Terra בחרו להטמיע את הפתרון הזה באמצעות fetch API עם עדיפות נמוכה בשילוב עם מופע של Intersection Observer. ב-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 לרשימה לצורך אחסון מקדים.
  • תהליך האחזור מראש מתוזמן באמצעות requestIdleCallback, במטרה להריץ את הפונקציה prefetch כשהשרשור הראשי לא פעיל.

סיכום

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

תודה מיוחדת ל-Gilberto Cocchi, ‏ Harry Theodoulou, ‏ Miguel Carlos Martínez Díaz, ‏ Barry Pollard, ‏ Jeremy Wagner, ‏ Leonardo Bellini ו-Lucca Paradeda מצוות המהנדסים של Terra על התרומה שלהם לעבודה הזו.