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

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

David Belford
David Belford

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

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

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

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

TBT כשרת proxy של INP

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

הקורלציה הזו, יחד עם החששות של בעלי האתרים לגבי TBT, הובילה את Taboola להתמקד ולצמצם את התרומה שלה למדד הזה.

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

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

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

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

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

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

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

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

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

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

הנתונים שנאספו באמצעות 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, הכלי 'הבהרת הביצועים' יכול לפצל את המשימות האלה לפני שהוא מעביר את השליטה ל-thread הראשי באמצעות scheduler.postTask(). התכנון הזה מבטיח שאפשר לבצע משימות קריטיות שמוצגות למשתמשים – כמו עיבוד הגרפי של עדכונים – בהקדם האפשרי, ללא קשר למשימות קיימות שעשויות להשתמש בשרשור הראשי.

זהו קטע ה-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 ושל 'הקטנת ההצגה של מודעות לפי ביצועים', Taboola ערכה ניסוי A/B למדידת ההכנסה ממודעות (INP) בהשוואה למנוע הקיים ללא יצירת הכנסות מסקריפט, בקבוצה של שותפי האתרים.

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

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

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

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

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

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

סיכום

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

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

תודה מיוחדת ל-Gilberto Cocchi, ל-Noam Rosenthal ול-Rick Viscomi מ-Google, ול-Dedi Hakak, ל-Anat Dagan ול-Omri Ariav מצוות המהנדסים והמוצרים של Taboola על התרומה שלהם לעבודה הזו.