หากต้องการปรับปรุงประสิทธิภาพการเลื่อน/ซูม wheel
เราขอแนะนำให้นักพัฒนาแอปลงทะเบียน wheel
และ Listener เหตุการณ์แบบแพสซีฟโดยส่งตัวเลือก {passive: true}
ไปยัง addEventListener()
mousewheel
การลงทะเบียน Listener เหตุการณ์แบบแพสซีฟจะบอกเบราว์เซอร์ว่า Listener วีลจะไม่เรียกใช้ preventDefault()
และเบราว์เซอร์จะเลื่อนและซูมได้อย่างปลอดภัยโดยไม่บล็อก Listener
ปัญหาคือส่วนใหญ่ Listener เหตุการณ์ของลูกกลิ้งเมาส์จะแบบเฉยๆ (อย่าเรียกใช้ preventDefault()
) แต่ไม่ได้ระบุไว้อย่างชัดเจน เช่น ทำให้เบราว์เซอร์รอให้การจัดการเหตุการณ์ JS เสร็จสิ้นก่อนจะเริ่มเลื่อน/ซูม แม้ว่าจะไม่จำเป็นต้องรอก็ตาม ใน Chrome 56
เราได้แก้ไขปัญหานี้สำหรับ touchstart
และ touchmove
แล้ว
และต่อมาทั้ง Safari และ Firefox ได้นำการเปลี่ยนแปลงดังกล่าวไปใช้ อย่างที่เห็นจากวิดีโอสาธิตที่เราทำขึ้นในตอนนั้น ทำให้ลักษณะการทำงานมีความล่าช้าอย่างเห็นได้ชัดในการตอบสนองการเลื่อน ตอนนี้ใน Chrome 73 เราได้ใช้การฝึกฝนแบบเดียวกัน
กับเหตุการณ์ wheel
และ mousewheel
การแทรกแซง
เป้าหมายของเราสำหรับการเปลี่ยนแปลงนี้คือการลดเวลาที่ใช้ในการอัปเดตจอแสดงผลหลังจากที่ผู้ใช้เริ่มเลื่อนด้วยล้อหรือทัชแพดโดยที่นักพัฒนาซอฟต์แวร์ไม่จำเป็นต้องเปลี่ยนโค้ด เมตริกของเราแสดงให้เห็นว่า 75% ของผู้ฟังเหตุการณ์ wheel
และ mousewheel
ที่ลงทะเบียนในเป้าหมายรูท (หน้าต่าง เอกสาร หรือเนื้อหา) ไม่ได้ระบุค่าใดๆ สำหรับตัวเลือกแบบแพสซีฟ และมากกว่า 98% ของผู้ฟังดังกล่าวไม่ได้เรียกใช้ preventDefault()
ใน Chrome 73 เราจะเปลี่ยน Listener wheel
และ mousewheel
ที่ลงทะเบียนในเป้าหมายรูท (หน้าต่าง เอกสาร หรือเนื้อความ) ให้เป็นแบบแพสซีฟโดยค่าเริ่มต้น ซึ่งหมายความว่า Listener
เหตุการณ์ เช่น
window.addEventListener("wheel", func);
จะเทียบเท่ากับ
window.addEventListener("wheel", func, {passive: true});
และระบบจะไม่สนใจการเรียก preventDefault()
ใน Listener ด้วยคำเตือนสำหรับเครื่องมือสำหรับนักพัฒนาเว็บต่อไปนี้
[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()
ภายใน Listener ที่ระบบจะถือว่าเป็นแบบแพสซีฟโดยค่าเริ่มต้น แอปพลิเคชันสามารถพิจารณาได้ว่าอาจเกิดปัญหาดังกล่าวหรือไม่โดยการตรวจสอบว่าการเรียกใช้ preventDefault()
ส่งผลใดๆ ผ่านพร็อพเพอร์ตี้ defaultPrevented
หรือไม่ การแก้ไขสำหรับเคสที่ได้รับผลกระทบค่อนข้างง่าย ด้วยการส่ง {passive: false}
ให้ addEventListener()
เพื่อลบล้างลักษณะการทำงานเริ่มต้นและคงตัวฟังเหตุการณ์เป็นการบล็อก