ตัวแฮนเดิลอินพุตอาจเป็นสาเหตุที่ทำให้เกิดปัญหาด้านประสิทธิภาพในแอป เนื่องจากตัวแฮนเดิลดังกล่าวอาจบล็อกเฟรมไม่ให้เสร็จสิ้นและอาจทำให้มีเลย์เอาต์เพิ่มขึ้นโดยไม่จำเป็น
ตัวแฮนเดิลอินพุตอาจเป็นสาเหตุของปัญหาด้านประสิทธิภาพในแอป เนื่องจากอาจบล็อกเฟรมไม่ให้ทำงานจนเสร็จสมบูรณ์ และอาจทำให้มีการออกแบบเพิ่มเติมโดยไม่จำเป็น
สรุป
- หลีกเลี่ยงตัวแฮนเดิลอินพุตที่ใช้เวลานาน เนื่องจากอาจบล็อกการเลื่อนได้
- อย่าเปลี่ยนแปลงรูปแบบในตัวแฮนเดิลอินพุต
- ดีดตัวแฮนเดิล จัดเก็บค่าเหตุการณ์ และจัดการกับการเปลี่ยนแปลงรูปแบบในโค้ดเรียกกลับ requestAnimationFrame ถัดไป
หลีกเลี่ยงตัวแฮนเดิลอินพุตที่ทํางานเป็นเวลานาน
ในกรณีที่เร็วที่สุดที่เป็นไปได้ เมื่อผู้ใช้โต้ตอบกับหน้าเว็บ ชุดข้อความ Compositor ของหน้าเว็บจะรับการป้อนข้อมูลด้วยการสัมผัสของผู้ใช้และย้ายเนื้อหาไปรอบๆ ซึ่งเทรดหลักไม่ต้องดำเนินการใดๆ ในส่วนของ JavaScript, เลย์เอาต์, สไตล์ หรือแสดงผล
![การเลื่อนขนาดเล็ก ใช้ตัวจัดวางองค์ประกอบเท่านั้น](https://web.developers.google.cn/static/articles/debounce-your-input-handlers/image/lightweight-scrolling-co-d1e531e7414ca.jpg?authuser=9&hl=th)
อย่างไรก็ตาม หากคุณแนบตัวแฮนเดิลอินพุต เช่น touchstart
, touchmove
หรือ touchend
เทรดของตัวคอมโพเนนต์ต้องรอให้ตัวแฮนเดิลนี้ทำงานให้เสร็จสิ้น เนื่องจากคุณอาจเลือกเรียกใช้ preventDefault()
และหยุดการเลื่อนด้วยการแตะได้ แม้จะไม่ได้เรียกใช้ preventDefault()
ตัวจัดวางองค์ประกอบก็ต้องรอ และทำให้การเลื่อนของผู้ใช้ถูกบล็อก ซึ่งอาจส่งผลให้เฟรมกระตุกและหลุดหายไปได้
![การเลื่อนมากเกินไป ตัวจัดวางองค์ประกอบถูกบล็อกใน JavaScript](https://web.developers.google.cn/static/articles/debounce-your-input-handlers/image/heavy-scrolling-composit-2d22d7b7e1daa.jpg?authuser=9&hl=th)
พูดง่ายๆ ก็คือคุณควรตรวจสอบว่าเครื่องจัดการอินพุตที่คุณเรียกใช้ควรดำเนินการได้อย่างรวดเร็วและอนุญาตให้ตัวจัดวางองค์ประกอบทำงานได้
หลีกเลี่ยงการเปลี่ยนแปลงรูปแบบในเครื่องจัดการอินพุต
ตัวแฮนเดิลอินพุต เช่น สำหรับการเลื่อนและการแตะ มีกำหนดเวลาให้ทำงานก่อนโค้ดเรียกกลับ requestAnimationFrame
ใดๆ
หากคุณทำการเปลี่ยนแปลงภาพภายในตัวแฮนเดิลดังกล่าว เมื่อเริ่มต้น requestAnimationFrame
จะมีการเปลี่ยนรูปแบบรอดำเนินการอยู่ หากคุณจากนั้นอ่านคุณสมบัติภาพในตอนต้นของโค้ดเรียกกลับ requestAnimationFrame ตามที่คำแนะนำใน "หลีกเลี่ยงเลย์เอาต์ขนาดใหญ่และซับซ้อนที่กดมาก" คุณจะทริกเกอร์เลย์เอาต์แบบซิงโครนัสแบบบังคับเลย
![การเลื่อนมากเกินไป ตัวจัดวางองค์ประกอบถูกบล็อกใน JavaScript](https://web.developers.google.cn/static/articles/debounce-your-input-handlers/image/heavy-scrolling-composit-151ee35865c54.jpg?authuser=9&hl=th)
ดีเฟ้นตัวแฮนเดิลการเลื่อน
วิธีแก้ปัญหาทั้ง 2 ข้อข้างต้นเหมือนกัน คือ คุณควรยกเลิกการเปลี่ยนแปลงภาพในโค้ดเรียกกลับ requestAnimationFrame
ครั้งถัดไปเสมอ
function onScroll (evt) {
// Store the scroll value for laterz.
lastScrollY = window.scrollY;
// Prevent multiple rAF callbacks.
if (scheduledAnimationFrame)
return;
scheduledAnimationFrame = true;
requestAnimationFrame(readAndUpdatePage);
}
window.addEventListener('scroll', onScroll);
การทําเช่นนี้ยังมีประโยชน์เพิ่มเติมคือให้ตัวแฮนเดิลอินพุตใช้ง่าย ซึ่งเป็นเรื่องที่ยอดเยี่ยม เนื่องจากตอนนี้คุณไม่ได้บล็อกสิ่งต่างๆ เช่น การเลื่อนหรือสัมผัสโค้ดราคาแพงที่คำนวณได้