วิธีแก้ไข INP: ทำอย่างไรไม่ให้แอป React รู้สึกช้า

แดชบอร์ดของคุณดูเหมือนจะช้า ทั้งที่ API ของคุณทำงานเร็ว และ Lighthouse ก็แสดงคะแนนเป็นสีเขียว แต่ทุกครั้งที่คลิกกลับรู้สึกหน่วง

นั่นคือปัญหาเรื่อง INP

Interaction to Next Paint (INP) คือตัวชี้วัดระยะเวลาที่หน้าเว็บใช้ในการตอบสนองต่อผู้ใช้ โดยเข้ามาแทนที่ First Input Delay (FID) เมื่อเดือนมีนาคม 2024 ซึ่ง FID จะดูแค่การคลิกครั้งแรกเท่านั้น แต่ INP จะติดตามทุกการตอบสนอง (interaction)

คะแนน INP ที่ต่ำกว่า 200 ms จะให้ความรู้สึกที่รวดเร็ว ส่วนที่มากกว่า 500 ms จะเริ่มรู้สึกหน่วง

ในการแก้ไข INP ให้แบ่งออกเป็นสามระยะ ดังนี้:

  • Input Delay – ช่วงเวลาระหว่างการคลิกจนถึงตอนที่โค้ดของคุณเริ่มทำงาน มักเกิดขึ้นเมื่อ main thread กำลังทำงานหนักอยู่
  • Processing Time – ระยะเวลาที่ฟังก์ชันและการอัปเดต React state ของคุณทำงาน
  • Presentation Delay – ช่วงเวลาระหว่างการทำงานของโค้ดเสร็จสิ้นจนถึงตอนที่เบราว์เซอร์วาดภาพ (paint) ลงบนหน้าจอ

วิธีแก้ไข Input Delay

งานที่ใช้เวลานาน (Long tasks) จะไปบล็อก main thread หากงานใดทำงานนานกว่า 50 ms จะทำให้การคลิกหยุดชะงัก ให้เรียกใช้ scheduler.yield() เพื่อแบ่งงานที่ยาวเกินไปออกเป็นส่วนย่อยๆ เพื่อให้เบราว์เซอร์สามารถประมวลผลการคลิกแทรกระหว่างงานเหล่านั้นได้

วิธีแก้ไข Processing Time

ใช้ transition APIs ของ React เพื่อรักษาความลื่นไหลของ UI

  • startTransition – ใช้ครอบการอัปเดตที่ไม่เร่งด่วน เพื่อให้ React สามารถหยุดการอัปเดตที่หนักหน่วงชั่วคราวเพื่อไปจัดการกับการคลิกใหม่ได้
  • useDeferredValue – ใช้หน่วงเวลาค่า (values) ที่ไม่จำเป็นต้องอัปเดตในทันที

API เหล่านี้ไม่ได้ช่วยให้โค้ดทำงานเร็วขึ้น แต่ช่วยให้โค้ดสามารถถูกขัดจังหวะได้ (interruptible) ซึ่งจะช่วยลดค่า INP ของคุณลง

วิธีแก้ไข Presentation Delay

องค์ประกอบ DOM ที่มากเกินไปจะทำให้การวาดภาพ (paint) ช้าลง

  • ใช้ content-visibility: auto ใน CSS เพื่อข้ามการเรนเดอร์องค์ประกอบที่อยู่นอกหน้าจอ
  • หยุดการเกิด layout thrashing: อย่าอ่านค่า style แล้วเขียนค่า style ต่อกันใน loop เดียวกัน แต่ให้ใช้วิธีรวบรวมการอ่านและการเขียน (batch reads and writes) แทน
  • ใช้การทำ Virtualization สำหรับรายการ (lists) ที่มีความยาวมาก

วิธีการวัดผล

Lighthouse ทำงานในสภาพแวดล้อมจำลอง (lab) จึงไม่สามารถคลิกปุ่มต่างๆ เหมือนคนจริงๆ ได้ ให้ติดตั้งไลบรารี web-vitals เพื่อเก็บข้อมูลจริงจากผู้ใช้งานของคุณ

ที่มา: https://dev.to/ahmed_mahmoud360/fixing-inp-field-notes-on-interaction-to-next-paint-in-a-react-app-32fa