כדי לשפר את הביצועים של wheel
בגלילה או בהגדלת התצוגה, מפתחים מומלצים לרשום פונקציות event listener של wheel
ו-mousewheel
כפסיביות על ידי העברת האפשרות {passive: true}
אל addEventListener()
. רישום של פונקציות ה-event listener כפונקציות פסיביות מאפשר לדפדפן לדעת שפונקציות ה-listener של הגלגל לא יקראו ל-preventDefault()
, ולדפדפן לבצע בבטחה גלילה ושינוי מרחק התצוגה בלי לחסום את ה-listeners.
הבעיה היא שברוב המקרים, רכיבי המעקב אחרי אירועי גלילה הם פסיביים מבחינה מושגית (לא קוראים ל-preventDefault()
), אבל הם לא מצוינים ככאלה באופן מפורש, ולכן הדפדפן צריך להמתין לסיום הטיפול באירוע ב-JS לפני שהוא מתחיל לגלול או להתקרב, למרות שהמתנה לא נדרשת. ב-Chrome 56, תיקנו את הבעיה הזו עבור touchstart
ו-touchmove
, והשינוי הזה אומץ מאוחר יותר גם ב-Safari וגם ב-Firefox. כפי שאפשר לראות בסרטון ההדגמה שיצרנו באותו זמן, השארת ההתנהגות כפי שהיא גרמה לעיכוב ניכר בתגובה לגלילה. עכשיו, בגרסה 73 של Chrome, החלנו את אותה התערבות על אירועים מסוג wheel
ו-mousewheel
.
ההתערבות
המטרה של השינוי הזה היא לקצר את הזמן שלוקח לעדכן את המסך אחרי שהמשתמש מתחיל לגלול באמצעות הגלגל או משטח המגע, בלי שהמפתחים יצטרכו לשנות את הקוד. לפי המדדים שלנו, 75% ממאזני האירועים של wheel
ו-mousewheel
שנרשמו ביעדים ברמה הבסיסית (חלון, מסמך או גוף) לא מציינים ערכים לאפשרות הפסיבית, ויותר מ-98% ממאזני האירועים האלה לא קוראים ל-preventDefault()
. ב-Chrome 73, אנחנו משנים את המאזינים wheel
ו-mousewheel
שנרשמים ביעדים ברמה הבסיסית (חלון, מסמך או גוף) כך שיהיו פסיביים כברירת מחדל. המשמעות היא שפונקציית event listener כמו:
window.addEventListener("wheel", func);
הופך להיות שווה ערך ל-:
window.addEventListener("wheel", func, {passive: true});
קריאה ל-preventDefault()
בתוך המאזין תתעלם עם האזהרה הבאה ב-DevTools:
[Intervention] Unable to preventDefault inside passive event listener due
to target being treated as passive. See https://www.chromestatus.com/features/6662647093133312
שגיאות והנחיות
ברוב המקרים לא תבחינו בשינוי. רק במקרים נדירים (פחות מ-0.3% מהדפים לפי המדדים שלנו), יכול להיות שתתבצע גלילה או שינוי מרחק התצוגה לא מכוונים בגלל שהקריאה ל-preventDefault()
מתעלמת בתוך המאזינים שנחשבים כפסיביים כברירת מחדל. האפליקציה יכולה לקבוע אם היא נתקלת בבעיה הזו בשטח על ידי בדיקה אם לקריאה ל-preventDefault()
הייתה השפעה כלשהי דרך המאפיין defaultPrevented
. התיקון במקרים הרלוונטיים קל יחסית: מעבירים את הערך {passive: false}
אל addEventListener()
כדי לשנות את התנהגות ברירת המחדל ולשמור את מאזין האירועים כחוסם.