ดีเบาเวลาของเครื่องจัดการอินพุต

ตัวแฮนเดิลอินพุตอาจเป็นสาเหตุของปัญหาด้านประสิทธิภาพในแอป เนื่องจากอาจบล็อกไม่ให้เฟรมทำงานเสร็จ และอาจทำให้เกิดงานเลย์เอาต์เพิ่มเติมที่ไม่จำเป็น

ตัวแฮนเดิลอินพุตอาจเป็นสาเหตุของปัญหาด้านประสิทธิภาพในแอป เนื่องจากอาจบล็อกไม่ให้เฟรมทำงานเสร็จ และอาจทำให้เกิดงานเลย์เอาต์เพิ่มเติมที่ไม่จำเป็น

สรุป

  • หลีกเลี่ยงตัวแฮนเดิลอินพุตที่ใช้เวลานานในการทำงาน เนื่องจากอาจบล็อกการเลื่อน
  • อย่าทำการเปลี่ยนแปลงสไตล์ในตัวแฮนเดิลอินพุต
  • ดีเบานซ์ตัวแฮนเดิล จัดเก็บค่าเหตุการณ์ และจัดการการเปลี่ยนแปลงสไตล์ในฟังก์ชันเรียกกลับ requestAnimationFrame ครั้งถัดไป

หลีกเลี่ยงตัวแฮนเดิลอินพุตที่ใช้เวลานานในการทำงาน

ในกรณีที่เร็วที่สุดเท่าที่จะเป็นไปได้ เมื่อผู้ใช้โต้ตอบกับหน้าเว็บ เธรด Compositor ของหน้าเว็บจะรับอินพุตการสัมผัสของผู้ใช้และย้ายเนื้อหาไปมาได้ ซึ่งไม่จำเป็นต้องให้เธรดหลักทำงานใดๆ ที่ JavaScript, เลย์เอาต์, สไตล์ หรือการวาดภาพทำงาน

การเลื่อนที่ราบรื่น โดยมีความล่าช้าระหว่างการแตะของผู้ใช้และการคอมมิต GPU น้อยที่สุดด้วย Compositor เพียงอย่างเดียว

อย่างไรก็ตาม หากคุณแนบตัวแฮนเดิลอินพุต เช่น touchstart, touchmove หรือ touchend เธรด Compositor จะต้องรอให้ตัวแฮนเดิลนี้ทำงานเสร็จสิ้น เนื่องจากคุณอาจเลือกเรียก preventDefault() และหยุดการเลื่อนด้วยการสัมผัสไม่ให้เกิดขึ้น แม้ว่าคุณจะไม่เรียก preventDefault() แต่ Compositor ก็ต้องรอ และด้วยเหตุนี้การเลื่อนของผู้ใช้จึงถูกบล็อก ซึ่งอาจส่งผลให้เกิดการกระตุกแบบข้ามเฟรมและเฟรมขาดหายไป

การเลื่อนอย่างรวดเร็ว หลังจากที่ผู้ใช้แตะ ระบบจะบล็อกการเลื่อนและเลื่อนการคอมมิต GPU โดยตัวแฮนเดิล "onTouchMove"

กล่าวโดยย่อคือ คุณควรตรวจสอบว่าตัวแฮนเดิลอินพุตใดๆ ที่คุณเรียกใช้ควรทำงานอย่างรวดเร็วและอนุญาตให้ Compositor ทำงานของตนเองได้

หลีกเลี่ยงการเปลี่ยนแปลงสไตล์ในตัวแฮนเดิลอินพุต

ระบบจะกำหนดเวลาให้ตัวแฮนเดิลอินพุต เช่น ตัวแฮนเดิลสำหรับการเลื่อนและการสัมผัส ทำงานก่อนฟังก์ชันเรียกกลับ requestAnimationFrame

หากคุณทำการเปลี่ยนแปลงภาพภายในตัวแฮนเดิลเหล่านี้ เมื่อเริ่มต้น 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);

การดำเนินการนี้ยังมีประโยชน์เพิ่มเติมคือช่วยให้ตัวแฮนเดิลอินพุตมีขนาดเล็ก ซึ่งเป็นเรื่องดีเพราะตอนนี้คุณจะไม่บล็อกสิ่งต่างๆ เช่น การเลื่อนหรือการสัมผัสในโค้ดที่มีการคำนวณที่ซับซ้อน