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

Sahel Sharify
Sahel Sharify

เราขอแนะนำให้นักพัฒนาซอฟต์แวร์ลงทะเบียน Listener เหตุการณ์ของ wheel และ mousewheel เป็นแบบแพสซีฟเพื่อปรับปรุงประสิทธิภาพการเลื่อน/การซูม wheel โดยส่งตัวเลือก {passive: true} ไปยัง addEventListener() การลงทะเบียน Listener เหตุการณ์เป็นแบบแพสซีฟจะบอกให้เบราว์เซอร์ทราบว่า Listener ของล้อเลื่อนจะไม่เรียก preventDefault() และเบราว์เซอร์จะเลื่อนและซูมได้อย่างปลอดภัยโดยไม่ต้องบล็อก Listener

ปัญหาคือ ส่วนใหญ่แล้ว ฟังก์ชันการฟังเหตุการณ์การเลื่อนล้อมีลักษณะแบบพาสซีฟ (ไม่เรียก preventDefault()) แต่ไม่ได้ระบุไว้อย่างชัดเจนว่าเป็นเช่นนั้น ทำให้เบราว์เซอร์ต้องรอให้การจัดการเหตุการณ์ JS เสร็จสิ้นก่อนที่จะเริ่มเลื่อน/ซูม แม้ว่าจะไม่จำเป็นต้องรอก็ตาม ใน Chrome 56 เราแก้ไขปัญหานี้สำหรับ touchstart และ touchmove แล้ว ทั้ง Safari และ Firefox ได้นำการเปลี่ยนแปลงดังกล่าวมาใช้ในภายหลัง ดังที่คุณเห็นจากวิดีโอสาธิตที่เราจัดทำขึ้นในขณะนั้น การแสดงผลตามปกติจะทำให้เกิดความล่าช้าที่เห็นได้ชัดในการตอบสนองต่อการเลื่อน ใน Chrome 73 เราได้นําการแทรกแซงแบบเดียวกันไปใช้กับเหตุการณ์ wheel และ mousewheel

The Intervention

เป้าหมายของการเปลี่ยนแปลงนี้คือเพื่อลดเวลาที่ใช้ในการอัปเดตการแสดงผลหลังจากที่ผู้ใช้เริ่มเลื่อนด้วยล้อหรือทัชแพด โดยที่นักพัฒนาแอปไม่จําเป็นต้องเปลี่ยนโค้ด เมตริกของเราแสดงให้เห็นว่า 75% ของโปรแกรมรับเหตุการณ์ wheel และ mousewheel ที่ลงทะเบียนในเป้าหมายรูท (หน้าต่าง เอกสาร หรือบอดี้) ไม่ได้ระบุค่าใดๆ สําหรับตัวเลือกแบบพาสซีฟ และโปรแกรมรับเหตุการณ์ดังกล่าวมากกว่า 98% ไม่ได้เรียกใช้ preventDefault() ใน Chrome 73 เราจะเปลี่ยนตัวรับฟัง wheel และ mousewheel ที่ลงทะเบียนในเป้าหมายรูท (window, document หรือ body) ให้เป็นแบบพาสซีฟโดยค่าเริ่มต้น ซึ่งหมายความว่า 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() เพื่อลบล้างลักษณะการทำงานเริ่มต้นและเก็บเหตุการณ์ที่ฟังไว้เป็นบล็อก