למדו מהו השהיה לאחר קלט (פלט), והכירו שיטות להפחתת ההשפעה שלו, כדי להגביר את האינטראקטיביות.
אינטראקציות באינטרנט הן דברים מסובכים, וכל מיני סוגים של פעילויות מתרחשות בדפדפן כדי לעודד אותן. עם זאת, מה שמשותף לכולן הוא שיש עיכוב מסוים בהצגת הנתונים לפני שהקריאות החוזרות של האירועים שלהם יתחילו לפעול. במדריך הזה נסביר מהו עיכוב קלט ומה אפשר לעשות כדי לצמצם אותו כדי שהאינטראקציות באתר יפעלו מהר יותר.
מהו השהיה לאחר קלט?
עיכוב בקלט הוא פרק הזמן שמתחיל באינטראקציה הראשונה של המשתמש עם הדף, למשל הקשה על מסך, לחיצה עם עכבר או הקשה על מקש, עד לרגע שבו הקריאות החוזרות של האירוע מתחילות לפעול. כל אינטראקציה מתחילה בעיכוב מסוים בקלט.
חלק מסוים של העיכוב בקלט הוא בלתי נמנע: תמיד לוקח למערכת ההפעלה פרק זמן מסוים לזהות אירוע קלט ולהעביר אותו לדפדפן. עם זאת, בחלק הזה של העיכוב בקלט לא ניתן אפילו להבחין בחלק הזה, ויש דברים אחרים שקורים בדף עצמו שעלולים לגרום לעיכובים בקלט ארוכים מספיק כדי לגרום לבעיות.
מה המשמעות של העיכוב לאחר קלט
באופן כללי, רצוי שכל חלק באינטראקציה יהיה קצר ככל האפשר כדי שהאתר יעמוד בסף 'טוב' מאינטראקציה ועד הצגת התגובה (INP), ללא קשר למכשיר של המשתמש. בדיקת העיכוב בקלט הוא רק חלק אחד מהעמידה בסף הזה.
ייתכן שתתפתו לבחון את ערכי הסף של השהיה לאחר קלט ראשוני (FID) כדי לקבוע את קצב העיכוב בקלט – אבל הסף 'טוב' ל-FID הוא 100 אלפיות השנייה או פחות. אם תחרגו מסף זה, תקצו מחצית מהתקציב שלכם ל-INP לצורך חישוב העיכוב בלבד. לא מומלץ לעשות זאת אם לוקחים בחשבון שאינטראקציה גם מחייבת זמן להפעיל קריאות חוזרות של אירועים, וכדי שהדפדפן יצבע את המסגרת הבאה.
כדי לעמוד בסף 'הטוב' של INP, מומלץ לשאוף לעיכוב הקצר ביותר האפשרי בקלט, אבל אין צורך לבטל אותו לגמרי, כי זה בלתי אפשרי. כל עוד אתם נמנעים מעבודה מיותרת ב-thread הראשי בזמן שהמשתמשים מנסים ליצור אינטראקציה עם הדף, העיכוב בקלט אמור להיות נמוך מספיק כדי למנוע בעיות.
איך לצמצם את העיכוב בקלט
כפי שציינו קודם, לא ניתן להימנע מהשהיה מסוימת לאחר קלט, אבל מצד שני אפשר להימנע מהשהיה מסוימת לאחר קלט. הנה כמה דברים שכדאי לקחת בחשבון אם נתקלתם בעיכובים ארוכים בקלט.
כדאי להימנע משימוש בטיימרים חוזרים שמתחילים לעבוד יותר מדי על ה-thread הראשי
יש שתי פונקציות טיימר נפוצות ב-JavaScript שעשויות לגרום לעיכוב בקלט: setTimeout
ו-setInterval
. ההבדל בין השניים הוא ש-setTimeout
מתזמנת הפעלה חוזרת (callback) כך שתבוצע אחרי זמן מסוים. מצד שני, setInterval
מתזמנים קריאה חוזרת (callback) כך שיפעלו כל n אלפיות השנייה באופן קבוע, או עד שהטיימר מופסק במצב clearInterval
.
setTimeout
אינו בעייתי בפני עצמו - למעשה, הוא יכול לעזור בהימנעות ממשימות ארוכות. עם זאת, תלוי מתי הזמן הקצוב לתפוגה חלף, ואם המשתמש ינסה ליצור אינטראקציה עם הדף בזמן שהקריאה החוזרת לתפוגה פועלת.
בנוסף, ניתן להריץ את setTimeout
בלולאה או באופן חזרתי, במקרה שהוא פועל בצורה דומה יותר ל-setInterval
, אבל עדיף לא לתזמן את החזרה הבאה עד להשלמת הפעולה הקודמת. כלומר, הלולאה תוביל ל-thread הראשי בכל פעם שתתבצע קריאה ל-setTimeout
, אבל צריך לוודא שהקריאה החוזרת שלו לא גורמת לעומס יתר.
setInterval
מבצע פונקציית החזרה במרווחי זמן, ולכן יש סיכוי הרבה יותר גבוה שהיא תפריע לאינטראקציות. הסיבה לכך היא שבניגוד למופע יחיד של קריאה ל-setTimeout
, שהיא קריאה חוזרת וחד-פעמית שעשויה להפריע לאינטראקציה של המשתמש, האופי החוזר של setInterval
מאפשר למשתמש להפריע לאינטראקציה, וכך להגביר את השהיית הקלט של האינטראקציה.
אם טיימרים מתרחשים בקוד מאינטראקציה ישירה, יש לכם שליטה עליהם. בדקו אם אתם זקוקים להם, או עשו כמיטב יכולתכם כדי להפחית את העבודה בהם עד כמה שניתן. עם זאת, הטיימרים בסקריפטים של צד שלישי הם סיפור אחר. לעיתים קרובות אין לכם שליטה על הפעולות של סקריפט של צד שלישי. פתרון בעיות ביצועים בקוד של צד שלישי כרוך לעיתים קרובות בעבודה עם בעלי עניין כדי לקבוע אם סקריפט מסוים של צד שלישי נדרש. אם כן, עליכם ליצור קשר עם ספק סקריפטים של צד שלישי כדי לברר מה אפשר לעשות כדי לפתור בעיות בביצועים שהן עלולות לגרום לבעיות בביצועים באתר שלכם.
כדאי להימנע ממשימות ארוכות
אחת מהדרכים לצמצם עיכובים ארוכים בקלט היא להימנע ממשימות ארוכות. כשיש יותר מדי עבודה ב-thread הראשי שחוסמת את ה-thread הראשי במהלך האינטראקציות, היא גורמת לעיכוב בקליטת הנתונים לפני שהמשימות הארוכות מסתיימות.
מלבד צמצום כמות העבודה שאתם צריכים לבצע במשימה — ותמיד כדאי לשאוף לבצע כמה שפחות עבודה על ה-thread הראשי. אפשר לשפר את הרספונסיביות לקלט של המשתמשים על ידי פיצול משימות ארוכות.
שימו לב לחפיפה באינטראקציות
חלק מאתגר במיוחד באופטימיזציה של INP יכול להיות מצב שבו יש אינטראקציות חופפות. המשמעות של חפיפה בין אינטראקציות היא שלאחר שהייתה לך אינטראקציה עם רכיב אחד, ביצעת אינטראקציה נוספת עם הדף לפני שהאינטראקציה הראשונית הספיקה להציג את המסגרת הבאה.
מקורות החפיפה של האינטראקציה יכולים להיות פשוטים כמו משתמשים שמבצעים אינטראקציות רבות בפרק זמן קצר. מצב כזה עשוי לקרות כשמשתמשים מקלידים בשדות טופס, כאשר הרבה אינטראקציות במקלדת מתרחשות בפרק זמן קצר. אם העבודה על אירוע מרכזי היא יקרה במיוחד, כמו במקרה הנפוץ של שדות של השלמה אוטומטית, שבהם בקשות רשת נשלחות לקצה העורפי, עומדות לרשותכם שתי אפשרויות:
- כדאי לשקול ביטול יוצא של ערכי קלט כדי להגביל את מספר הפעמים שהאירוע של קריאה חוזרת (callback) מתבצע בפרק זמן נתון.
- אפשר להשתמש ב-
AbortController
כדי לבטל בקשות יוצאות שלfetch
כדי שה-thread הראשי לא יהיה עמוס בטיפול בקריאות חוזרות שלfetch
. הערה: אפשר להשתמש במאפייןsignal
של מכונהAbortController
גם כדי לבטל אירועים.
מקור נוסף לעיכוב בקלט כתוצאה מאינטראקציות חופפות יכול להיות אנימציות יקרות. באופן ספציפי, אנימציות ב-JavaScript עשויות להפעיל קריאות רבות של requestAnimationFrame
, שעלולות להפריע לאינטראקציות של המשתמשים. כדי לעקוף את הבעיה, כדאי להשתמש באנימציות CSS כשאפשר כדי להימנע מהוספת מסגרות אנימציה שעלולות להיות יקרות. אם עושים זאת, צריך להימנע מאנימציות לא מורכבות כדי שהאנימציות יפעלו בעיקר בשרשורים של ה-GPU ושל המחבר, ולא ב-thread הראשי.
סיכום
עיכובים בקלט עשויים שלא לייצג את רוב הזמן שלוקח לאינטראקציות, אבל חשוב להבין שלכל חלק באינטראקציה נדרש פרק זמן שאפשר לצמצם. אם אתם בודקים השהיה ארוכה של קלט, יש לכם הזדמנויות לצמצם אותה. כדי לצמצם את העיכוב בקלט ולהקל על משתמשי האתר, מומלץ להימנע מקריאות חוזרות (callback) קבועות, לחלק משימות ארוכות ולידיעה על חפיפה אפשרית בין אינטראקציות שונות.
תמונה ראשית (Hero) מתוך Un מועברים, מאת Erik Mclean.