פורסם: 14 באוקטובר 2025
מהירות התגובה לאינטראקציה באתר (INP) הוא מדד ליבה חשוב לבדיקת חוויית המשתמש באתר, שמשמש למדידת הרספונסיביות. ב-Fotocasa, Google Search Console הדגיש מספר משמעותי של דפים שהסטטוס שלהם השתנה ל'נדרש שיפור' ו'גרוע' כשמדד INP החליף את מדד מהירות התגובה לאינטראקציה ראשונה (FID) בשנת 2024. במקרה לדוגמה הזה מתוארים הכלים והאסטרטגיות שבהם השתמשנו כדי לאבחן ולפתור את הבעיות האלה, ובסופו של דבר לשפר באופן משמעותי את מדד ה-INP.
איפה התחיל הצוות של Fotocasa
לפני המעבר מ-FID ל-INP, כמעט כל דף במחשב ובנייד היה בתוך סף ה'טוב', כלומר כל המדדים הבסיסיים של חוויית המשתמש באותו זמן (LCP, CLS ו-FID) היו טובים. עם זאת, אחרי המעבר למדד INP, כמעט כל הדפים עברו לסיווג 'נדרש שיפור', וחלקם אפילו לסיווג 'גרוע', כי ערכי ה-INP חרגו באופן עקבי מ-200 מילישניות ברוב האינטראקציות של המשתמשים.
השינוי הזה גרם לצוות של Fotocasa להבין שהם מתעלמים מהיבט חשוב של חוויית המשתמש. המדד FID מודד רק את ההשהיה של האינטראקציה הראשונה, אבל המדד INP מעריך את הרספונסיביות של כל האינטראקציות, ומתחשב בהשהיות של עיבוד הקלט וההצגה. המדידה הרחבה הזו היא קירוב טוב בהרבה לאינטראקטיביות אמיתית (כפי שצוין על ידי Google) והיא הדגישה הזדמנויות שהוחמצו.
למרות ש-Google Search Console מספק נתוני ביצועים של שדות, הוא לא מספק תובנות בזמן אמת. הנתונים שלו מצטברים על פני חלון של 28 ימים, ולכן קשה לזהות בדיוק אילו אינטראקציות גרמו לבעיות באותו רגע.
היה צורך בדרך לעקוב אחרי INP בזמן אמת כדי לזהות את האינטראקציות שהיו הכי איטיות והכי נפוצות בקרב המשתמשים, ולשחזר אותן באופן מהימן בסביבות הפיתוח של הצוות. היה חשוב באותה מידה להבין את ההשפעה של השינויים שבוצעו, לא רק אילו תיקונים עזרו, אלא גם אילו שינויים גרמו בטעות להחמרה במצב.
לכן, השתמשנו בסדרת כלים כדי לאבחן את הבעיות ולפתור אותן. החשובים ביותר היו:
- כלי הפיתוח ל-Chrome, במיוחד הכרטיסייה Performance.
- מערכת RUM (Real User Monitoring) בהתאמה אישית שנבנתה על ידי צוות Fotocasa ב-Datadog באמצעות הספרייה web-vitals.
- הכלים למפתחים של React.
כלים לאבחון הבעיה
כדי לאבחן ולנפות באגים בבעיות בביצועים של INP, השתמשנו בכלים הבאים.
כלי הפיתוח ל-Google Chrome
דרך מצוינת לזהות ולשחזר בעיות שקשורות למדדי הליבה לבדיקת חוויית המשתמש באתר באפליקציית אינטרנט היא באמצעות הכרטיסייה Performance בכלי הפיתוח ל-Chrome של Google. בכרטיסייה 'ביצועים' נמדדים באופן אוטומטי המדדים הבסיסיים של חוויית המשתמש (Core Web Vitals), ומוצג משוב מיידי על מדדי הטעינה, האינטראקטיביות והזזת הפריסה. הנתונים האלה עקביים במידה רבה עם הנתונים שמוצגים בכלים אחרים של Google.
כדי לזהות ולפתור בעיות שקשורות ל-INP, הצוות של Fotocasa התחיל בדרך כלל בוויסות של המעבד (CPU) כדי לדמות את הביצועים של מכשירים ברמה נמוכה ובינונית. כך הצוות של Fotocasa יכול היה לראות איך הדף מתנהג בתנאים מגבילים יותר. לאחר מכן הסשן תועד באמצעות כלי הפרופיל והעקבות נותחו בקפידה, תוך התמקדות באינטראקציה של המשתמש כדי לאתר בעיות בביצועים.
כשמזהים צווארי בקבוק, כדאי במיוחד לבחון את חלקי המשנה של INP ואת המשימות שהדפדפן מבצע בכל אחד מהם. לדוגמה, בתמונה הבאה אפשר לראות שערך ה-INP גבוה למדי בגלל שני חישובים מחדש של סגנון שנגרמו על ידי שינויים בסגנון בגוף המסמך.
ב-Fotocasa הגדירו מערכת למעקב אחרי מדד ה-INP ומדדים אחרים של Core Web Vitals, כדי לוודא שכל בעיה בביצועים מזוהה ומטופלת במהירות. כשמדד מסוים עובר סף מסוים (על סמך טווחי הערכים שמוגדרים על ידי Google), השיוך נרשם ביומן כדי שאפשר יהיה לנתח את הבעיה ולפתור אותה.
במערכת הזו, נעשה שימוש בספריית web-vitals כדי לתעד את המדדים האלה ממשתמשים אמיתיים, באופן שתואם בדיוק לאופן שבו הם נמדדים על ידי Chrome ומדווחים לכלים אחרים של Google (כמו דוח חוויית המשתמש ב-Chrome, Page Speed Insights, דוח המהירות ב-Search Console ועוד).
כדי לקבל תצוגה מקיפה ולעקוב אחרי הנתונים באופן מרכזי, צוות Fotocasa השתמש ב-Datadog כדי לאסוף את הנתונים ולהציג אותם בצורה ויזואלית. כך הצוות יכול לקבל החלטות מושכלות שמבוססות על נתונים. המדדים המותאמים אישית מאפשרים להשיג יעילות בעלויות ולעקוב אחרי כמעט כל המשתמשים באתר Fotocasa.
המערכת הזו מאפשרת לצוות של Fotocase לעקוב במהירות אחרי ההשפעה של השינויים על המדדים, או אחרי שינויים בלתי צפויים שעלולים לפגוע בהם. אחר כך אפשר לפרק את מדד ה-INP לחלקים כמו השהיית קלט, משך העיבוד והשהיית הצגה, כדי לזהות בדיוק איזה חלק באינטראקציה אחראי בעיקר לזמני אינטראקציה ארוכים.
כשזוהו חריגות, כמו אלה שמוצגות באיורים 7 ו-8, חברת Fotocasa הגיבה במהירות והשתמשה ב-OpenSearch, כלי נוסף שעזר לה לאתר את המקום שבו השינוי עשוי להתרחש. הנתונים שסופקו על ידי ספריית web-vitals עזרו לזהות את היעד (רכיב ה-DOM שאחראי כנראה לערך גבוה של מדד) ועזרו לצוות להתמקד יותר בתיקון הבעיה.
בנוסף, אפשר להגדיר מסננים שונים, כמו סוג הדף, המכשיר או מצב הטעינה, כדי לייעל תרחישים ולהבין בצורה מדויקת יותר איך מדד INP מושפע.
React Developer Tools
השתמשנו ב-React Developer Tools כדי לשפר את יכולות הניפוי של Fotocasa. זהו כלי רב עוצמה שמאפשר להדגיש באופן חזותי רכיבים שעברו עיבוד מחדש.
כדי להפעיל את התכונה הזו, עוברים לכרטיסייה Profiler. אחר כך לוחצים על סמל גלגל השיניים בצד שמאל של הסרגל העליון, עוברים לכרטיסייה General (כללי) ומסמנים את התיבה Highlight updates when components render (הדגשת עדכונים כשמרכיבים מוצגים). כשהאפשרות הזו מופעלת, הרכיבים מודגשים כשהם עוברים עיבוד מחדש, וכך מתקבל ייצוג חזותי דינמי.
איך מבררים את הסיבה לעיבוד מחדש
אחרי שמזהים רכיב שעבר רינדור מחדש, השאלה הבאה היא "למה זה קרה?". כלי הפיתוח של React מספקים תשובה לשאלה הזו באמצעות תיאור כלי מועיל בתצוגת תרשים הלהבה.
כדי לגשת למידע הזה, צריך להקליט סשן של כלי הפרופיל. ניתוח הפלט של כלי הפרופיל יספק לכם מידע שימושי:
- בפינה השמאלית העליונה מוצג מספר הקומיטים של React.
- תרשים הלהבות מייצג באופן ויזואלי את עץ הרכיבים, והצבע האפור מציין רכיבים שלא עברו עיבוד מחדש. כל עמודה מייצגת רגע שבו עץ רכיבי React השתנה, ורגע שבו בוצע שינוי תואם ב-DOM.
- כשמעבירים את העכבר מעל כל רכיב בתרשים הלהבות, הסיבה לעיבוד מחדש שלו מוצגת בכותרת המשנה Why did this render? (למה הרכיב הזה עבר עיבוד?).
הסיבות לרינדור מחדש של רכיב יכולות להיות:
- זו הפעם הראשונה שהרכיב עבר עיבוד
- ההקשר השתנה
- ה-Hooks השתנו
- המאפיינים השתנו
- המצב שונה
- הרכיב הראשי עבר רינדור
איך בודקים את זמן הרינדור
הצבעים בתרשים הלהבה מעבירים מידע משמעותי. צבעים כמו גוונים שונים של כחול מציינים שרכיב מסוים דרש זמן עיבוד קצר יחסית בהשוואה לרכיבים אחרים. לעומת זאת, צבעים כמו כתום ואדום מציינים שרכיב מסוים דרש יותר זמן עיבוד.
איך צוות Fotocasa פתר את הבעיה
הסרה של רינדורים מיותרים
הרינדור מחדש מתבצע בכל פעם ש-React צריכה לעדכן את ממשק המשתמש בנתונים חדשים. הוא מגיע בדרך כלל מפעולת משתמש, מתגובה של API או מאירועים חשובים אחרים שדורשים עדכון של ממשק המשתמש. מכיוון שכל עיבוד מחדש מריץ JavaScript, יותר מדי עיבודים מחדש בבת אחת – במיוחד בעץ רכיבים גדול – עלולים לחסום את השרשור הראשי ולגרום לבעיות בביצועים.
יש שני סוגים של רינדור מחדש:
- עיבוד מחדש שנדרש: כשצריך לעדכן רכיב כי הוא מכיל נתונים חדשים או משתמש בהם.
- רינדורים מחדש מיותרים: כשמתבצע עדכון של רכיב בלי שינוי משמעותי, לרוב בגלל ניהול מצב לא יעיל או טיפול לא תקין במאפיינים.
בדרך כלל, כמה עיבודים מחדש מיותרים לא משפיעים באופן משמעותי, כי React מהיר מספיק כדי שהמשתמשים לא יבחינו בהם. עם זאת, אם הן מתרחשות לעיתים קרובות מדי או בעץ רכיבים גדול, הן עלולות לפגוע בחוויית המשתמש ולהשפיע לרעה על מדד ה-INP של הדף.
כך היה במקרה של צוות Fotocasa. הם הבינו שהאתר מבצע הרבה רינדורים מיותרים. הם התרחשו בשני תרחישים עיקריים:
- במהלך טעינת הדף: הגדלת מספר המשימות הארוכות ב-thread הראשי ודחיית האינטראקציה הראשונה, מה שהשפיע לרעה על מדד ה-INP של הדף.
- במהלך אינטראקציות של משתמשים: הגדלת זמן העיבוד של רוב האינטראקציות, מה שפגע גם ב-INP.
הרבה רכיבי עיבוד מחדש מיותרים עברו אופטימיזציה באתר Fotocasa. אחד מהשיפורים המשמעותיים ביותר שביצענו היה בדף החיפוש. היו שלוש טעינות מחדש מיותרות של רכיבים בטעינת הדף. אחרי שהסרנו את הפריטים האלה, ראינו את התוצאות הבאות:
- פחות משימות ארוכות (כפי שמוצג באיור הבא)
- זמן חסימה כולל קצר יותר (השוואה בין איור 14 לאיור 15)
מיקום משותף במדינה
מיקום לא נכון של מצב React עלול להאט את האפליקציה ולגרום לממשק המשתמש להיראות לא מגיב. כשמצב של רכיב משתנה, רכיבי הצאצא שלו יעברו עיבוד מחדש כברירת מחדל, אלא אם נעשה שימוש בפתרון עקיף (לדוגמה, memo).
כמו שמוסבר בקטע הקודם, רינדורים מחדש הם לא בהכרח דבר רע, אבל רינדור מחדש של כל הדף בגלל עדכון מצב ספציפי עלול להוביל לאינטראקציות איטיות יותר, כי עדכוני ה-DOM מתרחשים אחרי הרינדור.
לדוגמה, בדף החיפוש יש תיבת דו-שיח שמוצגים בה כל המסננים כשלוחצים על לחצן.
המצב ששולט במצב הפתוח של תיבת הדו-שיח במקרה הזה ממוקם בדף החיפוש. כשמצב הדף השתנה, כל הדף עבר עיבוד מחדש, מה שגרם לערך INP נמוך, במיוחד במכשירים איטיים יותר, כפי שאפשר לראות כשנעשה שימוש בהגבלת מהירות המעבד בכלי הפיתוח:
כדי לפתור את הבעיה, צריך לשנות את המצב כמה שיותר קרוב לרכיב שמפעיל את השינוי. במקרה הזה, אפשר להציב את המצב ברכיב הלחצן של המסננים, כך שכשהמצב ישתנה, רק הלחצן יעבור עיבוד מחדש.
הסרת מצבים מיותרים
אסור שהסטטוסים יכילו מידע מיותר או כפול. אם כן, זה עלול להוביל לעיבודים חוזרים מיותרים ולגרום לבעיות.
לדוגמה, בסרגל המסננים של Fotocasa, יש טקסט שמייצג את מספר המסננים שהוחלו על חיפוש מסוים:
מספר המסננים שהופעלו מחושב מתוך מצב האפליקציה. עם זאת, זה לא רק הוביל לרינדור מחדש מיותר של כל הרכיב, אלא גם לשינוי בפריסה במקרים מסוימים, כי הרכיב הזה עבר רינדור בצד השרת:
const [filtersCount, setFiltersCount] = useState(DEFAULT_COUNTER)
useEffect(() => {
const counter = filters
? Object.keys(filters)
?.reduce(reducerCounter, [])
?.filter((param) => searchParams?.[param]).length
: DEFAULT_COUNTER
setFiltersCount(counter)
}, [searchParams]);
כדי לפתור את הבעיה, הערך נגזר מאובייקט המסננים באמצעות משתנה במקום באמצעות מצב:
const counter = filters
? Object.keys(filters)
?.reduce(reducerCounter, [])
?.filter((param) => searchParams?.[param]).length
: DEFAULT_COUNTER;
הפחתת מספר העיבודים היקרים
כשמתרחשת אינטראקציה באפליקציית React, היא בדרך כלל מפעילה שינוי במצב. כמו שהוסבר קודם, כשמצב של רכיב משתנה, הרכיב יעבור עיבוד מחדש יחד עם כל רכיבי הצאצא שלו.
אם אחת מפונקציות העיבוד של הרכיבים האלה איטית, היא תשפיע לרעה על מדד ה-INP של הדף, כי סביר להניח שייווצר טאסק ארוך, וייקח יותר זמן לעדכן את ה-DOM.
צוות Fotocasa ניסה לצמצם ככל האפשר את החישובים שלוקחים הרבה זמן בפונקציית הרינדור של הרכיבים. הכלים למפתחים ב-Chrome והכלים למפתחים ב-React היו שימושיים מאוד בזיהוי פעולות רינדור איטיות.
השהיית ביצוע הקוד
בנוסף לאופטימיזציה של פונקציית הרינדור של רכיבים, בוצעה אופטימיזציה של פונקציות אחרות כדי לצמצם ככל האפשר את המשימות הארוכות. עם זאת, לא ניתן היה לבצע אופטימיזציה של חלק מהמשימות כי הן הסתמכו על קוד של צד שלישי.
דוגמה אחת הייתה ניתוח נתונים. במקרה הזה, הוחלט לדחות את ההרצה של קוד Analytics ולתת עדיפות לעדכונים של DOM כשמתרחשות אינטראקציות של משתמשים. כדי להשיג את זה, הצוות של Fotocasa השתמש בספרייה שנקראת idlefy, שגם דאגה לכך שקוד הניתוח ימשיך לפעול גם אם הדפדפן ייסגר מיד לאחר מכן.
תרבות של ביצועים
שיפור הביצועים הוא לא מאמץ חד-פעמי, אלא משהו שצריך לקחת בחשבון בכל תכונה שמופצת לסביבת הייצור. כל חברי הצוות צריכים להיות מתואמים, אחרת כמעט בלתי נמנע שיהיו נסיגות במדדים הבסיסיים של חוויית המשתמש (Core Web Vitals).
כדי להתמודד עם הבעיה, צוות Fotocasa שיתף באופן פעיל ידע בתוך הצוות וקבע מסגרת ברורה לזיהוי בעיות בביצועים על סמך נתוני Datadog RUM של Fotocasa, כולל הסבר איך לשחזר אותן. הוגדרו התראות לגבי מדדי הליבה לבדיקת חוויית המשתמש באתר – במיוחד מדד ה-INP – במערכת RUM, והן הוגדרו כך שיישלחו ישירות לצוות של Fotocasa ב-Slack. הגישה הזו אפשרה לנו לשמור על ביצועים אופטימליים ולזהות בעיות לפני שהן הפכו לנסיגות.
תוצאות
כדי לשפר את מדד INP באתר Fotocasa, היה צורך בשילוב של אופטימיזציות טכניות ושינויים תרבותיים. צוות Fotocasa הצליח להעביר את כל הדפים במחשב מהסטטוס 'דרוש שיפור' לסטטוס 'דפים מהירים' על ידי ביטול עיבודים חוזרים מיותרים, אופטימיזציה של מיקום המצב, הפחתה של עיבודים יקרים ודחייה של קוד לא קריטי. בנוסף, הצוות שיפר משמעותית את הדפים בנייד על ידי שדרוג של כמעט כל הדפים בסטטוס 'דרוש שיפור' ו'דפים איטיים' לסטטוס 'דפים מהירים'.
השינויים האלה שיפרו את חוויית המשתמש הכוללת באתר Fotocasa, ובשילוב עם יוזמות אחרות, הובילו לעלייה של 27% בשיעור ההמרות של מודעות ליצירת קשר ומודעות עם מספר טלפון, ובכך חיזקו באופן ישיר את מדדי הביצועים העיקריים של החברה.
הצוות של Fotocasa השתמש ב-Datadog כדי לעקוב אחרי השיפורים ב-INP בזמן אמת, לזהות במהירות אנומליות ולמנוע רגרסיות. מעבר להישגים האלה, ב-Fotocasa הצליחו גם להטמיע את נושא הביצועים באתר בתרבות הפיתוח שלהם, כדי להבטיח ש-INP ומדדי Core Web Vitals יישארו בראש סדר העדיפויות בכל גרסה.