איך Trendsol הפחיתה את INP ב-50% וכתוצאה מכך עלתה עלייה של 1% בשיעור הקליקים

בניתוח המקרה הזה מתוארת תהליך עבודה מפורט לניפוי באגים ושיפור של INP ב-React, שבו נעשה שימוש ב-Trendyol. התהליך מתבסס על כלים של Google כמו PageSpeed Insights‏ (PSI), ‏ Chrome DevTools ו-scheduler.yield API.

שני רכיבים קריטיים בכל אתר מסחר אלקטרוני הם דף כרטיס המוצר (PLP) ודף פרטי המוצר (PDP). תנועה במסחר אלקטרוני מגיעה לעיתים קרובות מדפי כרטיסי מוצר, דרך קמפיינים באימייל, רשתות חברתיות או מודעות. לכן חשוב לוודא שחוויית השימוש בדף המוצר תוכננה בקפידה כדי לקצר את משך הזמן הנדרש לביצוע רכישה. כדי להצליח, חשוב לתת עדיפות לאיכות חוויית המשתמש. במאמרים שפורסמו בכתבי עת, כמו Milliseconds Make Millions, כבר נחשף ההשפעה המשמעותית של ביצועי האינטרנט על הנכונות של הצרכנים להוציא כסף ולנהל אינטראקציה עם מותגים באינטרנט.

Trendyol היא פלטפורמת מסחר אלקטרוני עם כ-30 מיליון לקוחות ו-240,000 מוכרים. הפלטפורמה הזו הפכה אותנו לעסק הראשון בטורקיה עם שווי של יותר מ-10 מיליארד דולר, ולאחת מפלטפורמות המסחר האלקטרוני המובילות בעולם.

כדי להשיג את המטרה של מתן חוויית המשתמש הטובה ביותר האפשרית בקנה מידה נרחב, תוך שמירה על גמישות התוכן ועל עבודה עם גרסת React ישנה יותר, ב-Trendyol התמקדו במהירות התגובה לאינטראקציה באתר (INP) כמדד מפתח לשיפור. בניתוח המקרה הזה מתוארת הדרך שבה Trendyol שיפרה את מדד INP בדף ה-PLP שלה, וכתוצאה מכך הפחיתה ב-50% את מדד INP והגדילה ב-1% את המדד העסקי של תוצאות החיפוש.

תהליך החקירה של Trendyol על ידי INP

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

הדרך של Trendyol לשיפור INP ב-PLP שלה התחילה בניתוח מעמיק של חוויית המשתמש לפני ביצוע השיפורים. על סמך דוח PSI, חוויית השימוש האמיתית של PLP הייתה עם INP של 963 אלפיות שנייה בנייד, כפי שמוצג באיור הבא.

INP של Trendyol לפי נתוני CrUX ב-PageSpeed Insights. ב-5 בספטמבר 2023, זמן הטעינה של Trendyol היה 963 אלפיות השנייה, כלומר בטווח 'גרוע'.
נתוני ה-INP של Trendyol נכון ל-5 בספטמבר 2023 מ-PSI.

כדי להבטיח תגובה מהירה, בעלי אתרים צריכים לשאוף ל-INP שנמוך מ-200 אלפיות השנייה או שווה לו. כלומר, באותו זמן, ה-INP של Trendyol היה בטווח 'גרוע'.

למרבה המזל, PSI מספק גם נתוני שטח לדפים שכלולים בדוח לגבי חוויית המשתמש ב-Chrome‏ (CrUX) וגם נתוני אבחון מפורטים של מעבדה. לפי נתוני המעבדה, בדיקת זמן הביצוע של JavaScript ב-Lighthouse העלתה שהתסריט search-result-v2 השתמש ב-thread הראשי במשך זמן ארוך יותר מאשר תסריטים אחרים בדף.

דוח על מקורות של משימות ארוכות ב-Lighthouse לאתר Trendyol. אחד המקורות העיקריים למשימות ארוכות הוא סקריפט שמטפל בתוצאות חיפוש ב-PLP של Trendyol.
בדיקת זמן הביצוע של JavaScript ב-Trendyol מ-Lighthouse נכון ל-5 בספטמבר 2023 מ-PSI.

כדי לזהות צווארי בקבוק בעולם האמיתי, השתמשנו בלוח הביצועים ב-Chrome DevTools כדי לפתור את הבעיות בחוויית השימוש ב-PLP ולזהות את מקור הבעיה. הדמיה של ביצועים בנייד עם האטה של 4x במעבד בכלים של Chrome למפתחים חשפה משימה שנמשכת 700-900 אלפיות השנייה בשרשור הראשי. אם השרשור הראשי תפוס במשימות אחרות למשך יותר מ-50 אלפיות שנייה, יכול להיות שהוא לא יוכל להגיב לקלט של משתמשים בזמן, וכתוצאה מכך חוויית המשתמש תהיה גרועה.

צילום מסך של סשן יצירת פרופיל ביצועים בכלי הפיתוח ל-Chrome עבור PLP של Trendyol. המשימה הארוכה שמוצגת פועלת במשך 737.6 אלפיות השנייה, והיא חלק מקריאה חוזרת (callback) של Intersection Observer.
כלי לניתוחי ביצועים של משימות ארוכות ב-PLP של Trendyol בחלונית הביצועים ב-Chrome DevTools.

המשימה הארוכה ביותר נגרמה על ידי קריאה חוזרת (callback) של Intersection Observer API בסקריפט של תוצאות החיפוש בתוך רכיב React. בשלב הזה התחלנו לבחון את האפשרות לפצל את המשימה הארוכה הזו למקטעים קטנים, כדי לתת לדפדפן יותר הזדמנויות להגיב לעבודה בעדיפות גבוהה יותר – כולל אינטראקציות של משתמשים.

מסתבר שהשימוש בפעולה setState שמפעילה עיבוד מחדש של React בתוך פונקציית ה-callback של Intersection Observer כרוך בעלות גבוהה, שעלולה להוות בעיה במכשירים ברמה נמוכה כי היא תופסת את השרשור הראשי למשך זמן רב מדי.

אחת מהשיטות שבהן המפתחים השתמשו כדי לפצל משימות למשימות קטנות יותר היא setTimeout. השתמשנו בשיטה הזו כדי לדחות את הביצוע של הקריאה ל-setState למשימה נפרדת. אמנם setTimeout מאפשר לדחות את ביצוע ה-JavaScript, אבל הוא לא מספק שליטה על העדיפות. לכן הצטרפנו לגרסת המקור של תקופת הניסיון של scheduler.yield כדי להבטיח את המשך ביצוע הסקריפט אחרי העברת השליטה ל-thread הראשי:

/*
* Yielding method using scheduler.yield, falling back to setTimeout:
*/
async function yieldToMain() {
  if('scheduler' in window && 'yield' in scheduler) {
    return await scheduler.yield();
  }

  return new Promise(resolve => {
    setTimeout(resolve, 0);
  });
}

/*
* Yielding to the main thread before changing the state of the component:
*/
const observer = new IntersectionObserver((entries) => {
  entries.forEach(handleIntersection);
  const maxNumberOfEntries = Math.max(...this.intersectingEntries);

  if (Number.isFinite(maxNumberOfEntries)) {
    await this.yieldToMain();

    this.setState({ count: maxNumberOfEntries });
  }
}, { threshold: 0.5 });

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

צילום מסך של סשן יצירת פרופיל ביצועים בכלי הפיתוח ל-Chrome עבור PLP של Trendyol. המשימה הארוכה שרצה בעבר במשך 737.6 אלפיות השנייה מחולקת עכשיו לכמה משימות קטנות יותר.
המשימה מחולקת למשימות קטנות יותר.

חשוב לדעת ש-Trendyol משתמשת במסגרת PuzzleJs כדי להטמיע ארכיטקטורת מיקרו-חזית באמצעות React v16.9.0. אפשר להשיג את אותם ביצועים באמצעות React 18, אבל נכון לעכשיו, ל-Trendyol אין אפשרות לשדרג מסיבות שונות.

תוצאות עסקיות

כדי למדוד את ההשפעה של השיפור שהטמענו ב-INP, הרצנו בדיקת A/B כדי לראות איך המדדים העסקיים הושפעו. באופן כללי, השינויים שערכנו בדף פרטי המוצר הובילו לשיפור משמעותי, כולל הפחתה של 50% ב-INP ועלייה של 1% בשיעורי הקליקים מדף כרטיסי המוצר לדף פרטי המוצר בכל סשן של משתמש. בתרשים הבא אפשר לראות איך ערך ה-INP השתפר ב-PLP לאורך זמן:

צילום מסך של INP באחוזון ה-75 של Trendyol במהלך שישה חודשים. בסוף 6 החודשים, זמן הטעינה של Trendyol ירד לכמעט 650 אלפיות השנייה מ-1,400 אלפיות השנייה.
שיפורים של INP באחוזון ה-75 לאורך זמן.

סיכום

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

אם תעבירו את הבעלות על הפעילות לשרשור הראשי מדי פעם כדי לתת לדפדפן יותר הזדמנויות לבצע משימות דחופות, האתר שלכם יהיה רספונסיבי יותר והלקוחות ייהנו מחוויית משתמש טובה יותר. ממשקי API חדשים לניהול תזמון, כמו scheduler.yield(), מאפשרים לבצע את המשימה הזו בקלות רבה יותר.

תודה מיוחדת ל-Jeremy Wagner, ל-Barry Pollard ול-Houssein Djirdeh מ-Google, ולצוות ההנדסה של Trendyol על התרומה שלהם לעבודה הזו.