איך חברת Taboola השתמשה ב-LoAF כדי לשפר את ה-INP ב-36% עבור האתרים של שותפיה בעלי תוכן דיגיטלי.

איך טאבולה השתמשה ב-Long Animation Frames API (LoAF) ואימוץ אסטרטגיה חכמה של תפוקה, כדי לשפר את יכולת התגובה של האתרים של בעלי האתרים מבלי לפגוע בביצועי המודעות.

דייוויד בלפורד
דייוויד בלפורד
תירנו תיאם
תירנו תיאם

Interaction to Next Paint (INP) הוא מדד שמעריך את יכולת התגובה של האתר לקלט של משתמשים. מדד INP מודד את הזמן שעובר מהרגע שבו משתמש מתחיל אינטראקציה – למשל, לחיצה, הקשה או הקלדה – ועד למשוב החזותי שמתקבל. מדד INP נועד להחליף את 'עיכוב הקלט הראשון' (FID) כמדד ליבה לבדיקת חוויית המשתמש באתר במרץ 2024.

Taboola היא הפלטפורמה המובילה בעולם לגילוי תוכן, המתבססת על 500,000 המלצות בכל שנייה באינטרנט הפתוח. ההמלצות האלה מאפשרות ל-9,000 בעלי התוכן הדיגיטלי השותפים של Taboola לייצר הכנסות ולעורר עניין בקרב הקהלים שלהם. בעלי אתרים מציגים המלצות בדפים שלהם באמצעות JavaScript.

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

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

TBT כביטוי של INP

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

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

צילום מסך של ביקורת ב-Lighthouse לגבי משך הזמן של ה-thread הראשי שנחסם. ה-thread הראשי נחסם בסך הכול על ידי מספר סקריפטים למשך 2,630 אלפיות השנייה, ו-JavaScript של צד שלישי תרם לכך 712 אלפיות השנייה. הסקריפט Release.js של Taboola אחראי לרוב זמן החסימה של צדדים שלישיים, והוא מסתיים ב-691 אלפיות השנייה.
באמצעות המנוע הישן של Taboola, סקריפטים כמו RELEASE.js חוסמים את ה-thread הראשי למשך 691 אלפיות השנייה.

כדי להגביל את ההשפעה הפוטנציאלית על מדדי הליבה לבדיקת חוויית המשתמש באתר, חברת Tabolea השתמשה ב-TBT כמדד proxy ל-INP. כדי שהיא התחילה:

  • זיהוי ואופטימיזציה של סקריפטים בעייתיים בשדה באמצעות Long Tasks API.
  • הערכת תרומות TBT באמצעות PageSpeed Insights API כדי להעריך 10,000 עד 15,000 כתובות URL ביום.

עם זאת, טאבולה זיהתה שלניתוח של TBT באמצעות הכלים האלה יש כמה מגבלות:

  • לא ניתן לשייך את המשימה לדומיין המקור או לסקריפט מסוים ב-Long Tasks API, ולכן קשה יותר לזהות מקורות של משימות ארוכות.
  • ה-Long Tasks API מזהה רק משימות ארוכות, ולא שילוב של משימות ושינויים בפריסה שעלולים לגרום לעיכוב בעיבוד.

כדי להתמודד עם האתגרים האלה, Taboola הצטרפה לגרסת המקור לניסיון של Long Animation Frames (LoAF) API בניסיון להבין טוב יותר את ההשפעה האמיתית שלה על התגובה לקלט של משתמשים. גרסאות ניסיון ראשוניות מעניקות גישה לתכונות חדשות או ניסיוניות, ומאפשרות למפתחים לבדוק תכונות חדשות שהמשתמשים שלהם יכולים לנסות, למשך זמן מוגבל.

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

שימוש ב-LoAF להערכת ההשפעה של INP

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

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

קוד ה-JavaScript הבא הוא גרסה פשוטה יותר שמשמשת לייצור של איסוף נתונים ב-LoAF כדי לבודד את ההשפעה של טאבולה.

function loafEntryAnalysis (entry) {
  if (entry.blockingDuration === 0) {
    return;
  }

  let taboolaIsMajor = false;
  const hasInteraction = entry.firstUIEventTimestamp > 0;
  let taboolaDuration = 0;
  const nonTaboolaLoafReport = {};
  const taboolaLoafReport = {};

  entry.scripts.forEach((script) => {
    const taboolaScriptBlockingDuration = handleLongAnimationFrameScript(script, taboolaLoafReport, nonTaboolaLoafReport);
    taboolaDuration += taboolaScriptBlockingDuration;

    if (taboolaScriptBlockingDuration > 0 || taboolaDuration > entry.duration / 2) {
      taboolaIsMajor = true;
    }
  });

  generateToboolaLoafReport(taboolaLoafReport, nonTaboolaLoafReport, hasInteraction, taboolaIsMajor);

  if (hasInteraction) {
    const global = _longAnimationFramesReport.global;
    global.inpBlockingDuration = Math.max(global.inpBlockingDuration, entry.blockingDuration);

    if (taboolaIsMajor) {
      global.taboolaInpBlockingDuration = Math.max(global.taboolaInpBlockingDuration, entry.blockingDuration);
    }
  }
}

const observer = new PerformanceObserver(list => {
  for (const entry of list.getEntries()) {
    loafEntryAnalysis(entry);
  }
});

observer.observe({ type: 'long-animation-frame', buffered: true });
  • השימוש בפונקציה loafEntryAnalysis אפשר ל-Taboola לזהות ערכים שבהם היא הגורם המשמעותי ביותר.
  • Tabבולה נחשבת לגורם מרכזי ביצירת התוכן אם היא נגרמה על ידי יותר ממחצית ממשך הזמן הכולל של הסקריפט, או אם הרצת הסקריפט של Tabola נמשכת יותר מ-50 אלפיות השנייה.
  • firstUIEventTimeStamp נוצר אם האינטראקציה של המשתמש מתעכבת עקב מסגרת אנימציה ארוכה. משך החסימה הארוך ביותר נחשב כציון ה-INP הכולל. אנחנו יכולים גם לזהות מתי Taboola הפעילה firstUIEventTimeStamp כדי לחשב ציון INP של Tabola.

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

Script משך (אלפיות שנייה)
vpaid/units/33_6_8/infra/cmTagINLINE_INSTREAM.js:106517 997
vpaid/units/33_6_8/infra/cmTagFEED_MANAGER.js:496662 561
vpaid/vPlayer/player/v15.8.6/OvaMediaPlayer.js:44631 336
libtrc/impl.20231212-23-RELEASE.js:821090 857
publisher_name/pmk-20220605.5.js:7728 336
libtrc/card-interference-detector.20231219-7-RELEASE.es6.js:183 239
רשומות של סקריפטים של LoAF שתועדו על ידי Taboola RUM

TRECS Engine: האסטרטגיה החדשה לתפוקה

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

TRECS (Taboola Recommendations Extensible Client Service) שומר על הרינדור בצד הלקוח ועל קוד ה-JS הנוכחי של בעל התוכן הדיגיטלי, תוך צמצום המספר והגודל של קובצי החובה שנדרשים כדי לטעון את ההמלצות של Taboola.

לאחר זיהוי משימות שחוסמות עיבוד באמצעות LoAF, הכלי Performance Fader יכול לפצל את המשימות האלה לפני העברה ל-thread הראשי באמצעות scheduler.postTask(). העיצוב הזה מבטיח שאפשר יהיה לבצע בהקדם האפשרי עבודה חיונית שגלויה למשתמשים – כמו עדכוני רינדור, בלי קשר למשימות קיימות שאוכלסות את ה-thread הראשי.

זהו קטע הקוד של ה-JS של הפעלת המשימה 'Performance Fader':

/**
* Send a task to run using the Fader. The task will run using the browser Scheduler, by the configuration settings, or immediately.
* @param task
* @param isBlocker
*/
function sendTaskToFader (task, isBlocker = true) {
  const publisherFaderChoice = fillOptimizationGlobals(); // Loading publisher choice
  const applyYielding = publisherFaderChoice === OptimizationFaderType.Responsiveness;

  if (applyYielding) {
    return runAsPostTask(task, isBlocker);
  }

  return runImmediately(task);
}

/**
* Yielding method using scheduler.postTask and falling back to setTimeout when it's not availabe based on the publisher choice
*/
function runAsPostTask (task, isBlocker = true) {
  if ('scheduler' in window && 'postTask' in scheduler) {
    const priority = isBlocker ? 'user-blocking': 'background';

    return window?.scheduler?.postTask(task, { priority });
  }

  const publisherChoiceEnableFallback = fillPublisherChoices();

  if (publisherChoiceEnableFallback) {
    return new Promise(resolve => {
      window.setTimeout(() => {
        resolve(task());
      }, 0);
    });
  }

  return runImmediately(task);
}

הפונקציה sendTaskToFader:

  • משתמש ב-runAsPostTask, שמשתמש ב-scheduler.postTask() מאחורי הקלעים (אם ה-API זמין), או חוזר אל setTimeout.
  • הפונקציה הזו ממירה קריאות לפונקציה בקטעי קוד הגורמים לפריימים ארוכים של אנימציה ול-INP. הוא מפצל את קטעי הקוד האלה למשימות קצרות יותר, וכתוצאה מכך מפחית את ה-INP.

מדדים עסקיים

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

כדי לקבוע את ההשפעה של TRECS ו-Performance Fader, ערכה טבולה בדיקת A/B למדידת INP לעומת המנוע הקיים, מבלי שהניב סקריפטים מפאנל של שותפים בעלי תוכן דיגיטלי.

בטבלה הבאה מוצגות תוצאות INP באלפיות השנייה באחוזון ה-75 של ארבעה בעלי תוכן דיגיטלי אנונימיים ברשת Taboola.

בעלי תוכן דיגיטלי INP עם TRECS + Performance Fader INP עם המנוע הקיים ירידה במדד INP (%)
בעל אפליקציה א' 48 75 36%
בעל אתר ב' 153 163 6%
בעל אתר ג' 92 135 33%
בעל אתר ד' 37 52 29%

למרבה המזל, מדדים עסקיים, כמו שיעור הקליקים על מודעה והכנסה לאלף חשיפות (RPM), לא הושפעו לרעה כשבלוח הבדיקה הופעלו מדדים עסקיים של TRECS ו-Performance Fader. בעקבות השיפור החיובי הזה ב-INP ללא כל תוצאה שלילית כמצופה במדדי ה-KPI של Google Ads, תשפר בהדרגה חברת Taboola את התפיסה של בעלי האפליקציות לגבי המוצר.

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

צילום מסך של בדיקה ב-Lighthouse לגבי זמן החסימה של ה-thread הראשי אחרי החלת המנועים החדשים TRECS ו-Performance Fader, כדי לשפר את זמן החסימה של ה-thread הראשי. הביקורת קוצרה ל-206 אלפיות השנייה בלבד, בהשוואה ל-712 אלפיות השנייה לפני שבוצעו האופטימיזציות.
המנוע החדש של Taboola עזר לסקריפטים כמו RELEASE.js להפחית את TBT ב-485 אלפיות השנייה (-70%).

ניתן לראות ששימוש ב-LoAF לזיהוי הסיבות ל-INP ופריסה של שיטות התפוקה הבאות עם Performance Fader מאפשרים לשותפים של Taboola להשיג הצלחה מרבית בביצועי המודעות והדפים.

סיכום

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

כשמשתמשים ב-LoAF בשילוב עם אסטרטגיית תפוקה טובה — כמו שימוש ב-scheduler.postTask() — אפשר להיעזר ב-LoAF כדי לזהות ולהבין את הסיבה למהירות תגובה נמוכה בדף, שעוזרת לכם לקבל את המידע הדרוש כדי לשפר את ה-INP של האתר.

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