ตัวแฮนเดิลอินพุตอาจเป็นสาเหตุของปัญหาด้านประสิทธิภาพในแอป เนื่องจากอาจบล็อกไม่ให้เฟรมทำงานเสร็จ และอาจทำให้เกิดงานเลย์เอาต์เพิ่มเติมที่ไม่จำเป็น
ตัวแฮนเดิลอินพุตอาจเป็นสาเหตุของปัญหาด้านประสิทธิภาพในแอป เนื่องจากอาจบล็อกไม่ให้เฟรมทำงานเสร็จ และอาจทำให้เกิดงานเลย์เอาต์เพิ่มเติมที่ไม่จำเป็น
สรุป
- หลีกเลี่ยงตัวแฮนเดิลอินพุตที่ใช้เวลานานในการทำงาน เนื่องจากอาจบล็อกการเลื่อน
- อย่าทำการเปลี่ยนแปลงสไตล์ในตัวแฮนเดิลอินพุต
- ดีเบานซ์ตัวแฮนเดิล จัดเก็บค่าเหตุการณ์ และจัดการการเปลี่ยนแปลงสไตล์ในฟังก์ชันเรียกกลับ requestAnimationFrame ครั้งถัดไป
หลีกเลี่ยงตัวแฮนเดิลอินพุตที่ใช้เวลานานในการทำงาน
ในกรณีที่เร็วที่สุดเท่าที่จะเป็นไปได้ เมื่อผู้ใช้โต้ตอบกับหน้าเว็บ เธรด Compositor ของหน้าเว็บจะรับอินพุตการสัมผัสของผู้ใช้และย้ายเนื้อหาไปมาได้ ซึ่งไม่จำเป็นต้องให้เธรดหลักทำงานใดๆ ที่ JavaScript, เลย์เอาต์, สไตล์ หรือการวาดภาพทำงาน
อย่างไรก็ตาม หากคุณแนบตัวแฮนเดิลอินพุต เช่น touchstart, touchmove หรือ touchend เธรด Compositor จะต้องรอให้ตัวแฮนเดิลนี้ทำงานเสร็จสิ้น เนื่องจากคุณอาจเลือกเรียก preventDefault() และหยุดการเลื่อนด้วยการสัมผัสไม่ให้เกิดขึ้น แม้ว่าคุณจะไม่เรียก preventDefault() แต่ Compositor ก็ต้องรอ และด้วยเหตุนี้การเลื่อนของผู้ใช้จึงถูกบล็อก ซึ่งอาจส่งผลให้เกิดการกระตุกแบบข้ามเฟรมและเฟรมขาดหายไป
กล่าวโดยย่อคือ คุณควรตรวจสอบว่าตัวแฮนเดิลอินพุตใดๆ ที่คุณเรียกใช้ควรทำงานอย่างรวดเร็วและอนุญาตให้ Compositor ทำงานของตนเองได้
หลีกเลี่ยงการเปลี่ยนแปลงสไตล์ในตัวแฮนเดิลอินพุต
ระบบจะกำหนดเวลาให้ตัวแฮนเดิลอินพุต เช่น ตัวแฮนเดิลสำหรับการเลื่อนและการสัมผัส ทำงานก่อนฟังก์ชันเรียกกลับ requestAnimationFrame
หากคุณทำการเปลี่ยนแปลงภาพภายในตัวแฮนเดิลเหล่านี้ เมื่อเริ่มต้น requestAnimationFrame จะมีการเปลี่ยนแปลงสไตล์ที่รอดำเนินการ หากคุณ จากนั้น อ่านพร็อพเพอร์ตี้ภาพเมื่อเริ่มต้นฟังก์ชันเรียกกลับ requestAnimationFrame ตามคำแนะนำใน “หลีกเลี่ยงเลย์เอาต์ขนาดใหญ่และซับซ้อน รวมถึงการเปลี่ยนแปลงเลย์เอาต์ซ้ำๆ” คุณจะทริกเกอร์เลย์เอาต์แบบซิงโครนัสที่บังคับ!
ดีเบานซ์ตัวแฮนเดิลการเลื่อน
วิธีแก้ปัญหาทั้ง 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);
การดำเนินการนี้ยังมีประโยชน์เพิ่มเติมคือช่วยให้ตัวแฮนเดิลอินพุตมีขนาดเล็ก ซึ่งเป็นเรื่องดีเพราะตอนนี้คุณจะไม่บล็อกสิ่งต่างๆ เช่น การเลื่อนหรือการสัมผัสในโค้ดที่มีการคำนวณที่ซับซ้อน