การทําให้การเลื่อนล้อเลื่อนเร็วโดยค่าเริ่มต้น

Sahel Sharify
Sahel Sharify

หากต้องการปรับปรุงประสิทธิภาพการเลื่อน/ซูม 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() เพื่อลบล้างลักษณะการทำงานเริ่มต้นและคงตัวฟังเหตุการณ์เป็นการบล็อก