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

איך שימוש ב-Long Animation Frames API ואימוץ אסטרטגיית תפוקה חכמה אפשרו ל-Taboola לשפר את ביצועי המודעות של בעלי תוכן דיגיטלי רספונסיביות של האתר בלי לפגוע בביצועי המודעות.

David Belford
David Belford

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

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

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

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

TBT כשרת proxy של 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 אלפיות השנייה.

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

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

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

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

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

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

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

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

הנה קטע הקוד של ה-JS של '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%

למרבה המזל, מדדים עסקיים כמו שיעור הקליקים על מודעות והכנסה ל-1,000 חשיפות (RPM) לא הושפעו לרעה כש-TRECS ו-Performance Fader הופעלו בחלונית הבדיקה. בעקבות השיפור החיובי הזה ב-INP ללא תוצאות שליליות כמצופה במדדי ה-KPI של המודעות, 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 לסקריפטים ספציפיים מבטל את הצורך לעסוק בניחושים ובנזקים אפשריים למדדים אחרים של ביצועי האתר. LoAF API הוכיח את עצמו ככלי שימושי לזיהוי ולטיפול בבעיות INP במיוחד עבור צדדים שלישיים שמוטמעים. הוא מאפשר להם לזהות הזדמנויות ספציפיות לשיפור ה-SDK שלהם, תוך ביטול הפרעות מטכנולוגיות אחרות שקיימות בדף.

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

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