מסע לפתרון INP של ה-EEA

הפחתת זמן הטעינה של דף הבית פי 30 והמעבר ל-Next.js עזרו ל-The Ecomonic Times לצמצם את זמן הטעינה של דף הנחיתה פי ארבע, וכתוצאה מכך חל ירידה של 50% בשיעור העזיבה ועלייה של 43% במספר הצפיות בדפים.

Daya Ram Yadav
Daya Ram Yadav
Saurabh Rajpal
Saurabh Rajpal

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

ערכים טובים של INP הם 200 אלפיות שנייה או פחות, ערכים גרועים הם יותר מ-500 אלפיות שנייה, וכל ערך בטווח שביניהם טעון שיפור.

ההתחלה המטושטשת

כש-Google הציגה לראשונה את המדד INP כמדד ניסיוני שעשוי להתפתח לאחד מהמדדים של Core Web Vitals, צוות Economic Times קיבל על עצמו את האתגר לתקן אותו לפני שהוא יהפוך למדד כזה, כי מתן חוויית משתמש ברמה עולמית הוא ערך מרכזי בעסק שלנו.

מדד INP היה אחד המדדים הקשים ביותר לפתרון עד כה. בהתחלה לא היה ברור איך למדוד את INP בצורה יעילה. מה שהקשה על התהליך היה חוסר התמיכה של הקהילה, כולל רוב ספקי המעקב אחר משתמשים אמיתיים (RUM) שעדיין לא תומכים בכך. עם זאת, היו לנו כלים של Google RUM, כמו דוח חוויית המשתמש ב-Chrome‏ (CrUX), ספריית JavaScript‏ web-vitals וכלים אחרים שתומכים בהם, שסייעו לנו להבין איפה אנחנו נמצאים בזמן שערכנו הערכה לגבי הדרך שצריך לבחור. כשהתחלנו, זמן ה-INP שלנו היה קרוב ל-1,000 אלפיות השנייה ברמת המקור.

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

מהי בדיקת TBT ואילו פעולות ביצענו כדי לשפר אותה?

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

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

  • משימה א' נמשכת 80 אלפיות שנייה (30 אלפיות שנייה יותר מ-50 אלפיות שנייה).
  • משימה ב' נמשכת 100 אלפיות השנייה (50 אלפיות השנייה יותר מ-50 אלפיות השנייה).

זמן הטעינה המשוער של הדף יהיה: 80 אלפיות השנייה (30 + 50). ככל שה-TBT נמוך יותר, כך טוב יותר. בנוסף, ל-TBT יש קורלציה טובה עם INP.

הנה השוואה מהירה של זמן הטעינה של דף הבית לפני ואחרי ביצוע פעולות לשיפורו:

תמונה מורכבת של משימות ארוכות במהלך ההפעלה, כפי שמוצג בחלונית הביצועים של כלי הפיתוח ל-Chrome, ודוח של מדדי דפים. ה-thread הראשי חסום במהלך טעינת הדף למשך 3,260 אלפיות השנייה.
השרשור הראשי במהלך ההפעלה לפני אופטימיזציה של TBT. הזמן הקצוב לתפוגה הוא 3,260 אלפיות השנייה.
תמונה מורכבת של משימות ארוכות במהלך ההפעלה, כפי שמוצג בחלונית הביצועים של כלי הפיתוח ל-Chrome, ודוח של מדדי דפים. ה-thread הראשי חסום במהלך טעינת הדף למשך 120 אלפיות השנייה.
השרשור הראשי במהלך ההפעלה אחרי אופטימיזציה של TBT. הזמן הקצוב לתפוגה הוא 120 אלפיות השנייה.

צמצום זמן העיבוד ב-thread הראשי

החוט הראשי של הדפדפן מטפל בכל מה שקשור לניתוח HTML, ליצירת DOM, לניתוח CSS ולהחלת סגנונות, וגם להערכה ולהפעלה של JavaScript. החוט הראשי מטפל גם באינטראקציות של משתמשים – כלומר, קליקים, הקשות על המסך והקשות על מקשים. אם השרשור הראשי עסוק בביצוע משימות אחרות, יכול להיות שהוא לא יגיב ביעילות לקלט של המשתמשים, וזה עלול להוביל לחוויית משתמש לא חלקה.

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

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

if ('requestIdleCallback' in window) {
 
this.requestIdleCallbackId = requestIdleCallback(fetchMarketsData.bind(this), {timeout: 3000});
} else {
  fetchMarketsData
(); // Fallback in case requestIdleCallback is not supported
}

מומלץ לציין זמן קצוב לתפוגה כשמשתמשים ב-requestIdleCallback, כי כך אפשר לוודא שאם הזמן שצוין חלף והקריאה החוזרת (callback) עדיין לא בוצעה, היא תתבצע מיד אחרי זמן הקצוב לתפוגה.

צמצום זמן ההערכה של הסקריפט

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

צילום מסך של כלי הכיסוי בכלי הפיתוח ל-Chrome. כאן הכלי מציג חלקים שלא בשימוש בקובצי JavaScript ו-CSS במהלך טעינת הדף.

צמצום הגודל של DOM

לפי Lighthouse, נפח DOM גדול מגביר את מידת השימוש בזיכרון, מאריך את הזמן הדרוש לחישובים חוזרים של סגנונות ומוביל להזרמה חוזרת של פריסות שגוזלת משאבים יקרים.

צילום מסך של הביקורת על גודל ה-DOM ב-Lighthouse. מספר רכיבי ה-DOM שדווחו הוא 2,706 רכיבים.

צמצמנו את מספר צומתי ה-DOM בשתי דרכים:

  • קודם, עיבדנו את פריטי התפריט שלנו לפי בקשת המשתמש (בקליק). הגודל של DOM ירד בכ-1,200 צמתים.
  • שנית, התמקדנו בטעינה איטית של ווידג'טים פחות חשובים.

בעקבות כל המאמצים האלה, הצלחנו לצמצם את זמן הטעינה של דפי הנחיתה באופן משמעותי, וכתוצאה מכך הצטמצם גם ה-INP שלנו בכמעט 50%:

צילום מסך של הביקורת של INP ב-CrUX. ערך ה-INP של הדף הוא 539 אלפיות השנייה, שהוא מעבר לסף 'גרוע'.

בשלב הזה כמעט נגמרו לנו הפתרונות הפשוטים שאפשר ליישם כדי לצמצם עוד יותר את ה-TBT (ואת ה-INP בעקיפין), אבל ידענו שיש לנו הרבה מקום לשיפור. בשלב הזה החלטנו לשדרג את תבנית ה-boilerplate המותאמת אישית של ממשק המשתמש לגרסה האחרונה של React יחד עם Next.js, כדי להשתמש טוב יותר בhooks ולהימנע מעיבוד מחדש מיותר של רכיבים.

בגלל העדכונים התכופים יותר והתנועה הנמוכה יחסית בהשוואה לחלקים האחרים באתר, התחלנו להעביר את דפי הנושאים שלנו ל-Next.js. השתמשנו גם ב-PartyTown כדי להעביר משימות כבדות נוספות של חוט הראשי לעובדים באינטרנט, יחד עם שיטות כמו requestIdleCallBack לדחיית משימות לא קריטיות.

איך שיפור ה-INP עזר ל-The Economic Times?

הערכים הנוכחיים של TBT ו-INP במקור

בזמן פרסום הפוסט הזה, זמן הטעינה הממוצע של המקור שלנו היה 120 אלפיות השנייה, ירידה מ-3,260 אלפיות השנייה כשהתחלנו את מאמצי האופטימיזציה. באופן דומה, זמן ה-INP של המקור שלנו ירד מיותר מ-1,000 אלפיות השנייה ל-257 אלפיות השנייה אחרי מאמצי האופטימיזציה שלנו.

צילום מסך של הביקורת של INP ב-CrUX. זמן הטעינה של הדף הוא 257 אלפיות השנייה, והוא נמצא בטווח הסף של 'נדרש שיפור'.

מגמת INP CrUX

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

צילום מסך של הפצות INP כפי שהן מוצגות ב-CrUX במשך ארבעה חודשים, מתחילת יולי 2022 ועד סוף אוקטובר 2022. הערכים בסף 'גרוע' ובסף 'דרוש שיפור' ירדו במקצת, בעוד שהערכים בסף 'טוב' עלו.

ניתוח TBT של Akamai mPulse

אנחנו משתמשים ב-Akamai mPulse כפתרון ה-RUM שלנו, שמודד את זמן הטעינה בפועל בשטח. ראינו ירידה עקבית ב-TBT, שמתאימה בבירור לתוצאות המאמצים שלנו לצמצום INP. כפי שאפשר לראות בצילום המסך שבהמשך, ערכי TBT ירדו בסופו של דבר מ-5 שניות בערך ל-200 אלפיות השנייה בשדה.

צילום מסך של תרשים ב-Akamai mPulse, שבו מוצג ירידה ב-TBT במשך כחודש.

תוצאה עסקית

באופן כללי, המאמצים שלנו לצמצם את זמן הטעינה של דף הבית פי 30, יחד עם המעבר ל-Next.js, עזרו לנו לצמצם את מספר הבקשות לטעינה מחדש פי 4 כמעט. בסופו של דבר, הפעולות האלה הובילו לירידה של 50% בשיעור העזיבה ולעלייה של 43% במספר הצפיות בדפים בנושאים.

צילום מסך של Google Analytics שבו מוצגת השוואה בין צפיות בדפים לבין שיעור העזיבה. בעקבות האופטימיזציות שבוצעו ב-INP באתר של The Economic Times, נרשמה ירידה של 50% בשיעור העזיבה ועלייה של 43% במספר הצפיות בדפים.

סיכום

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