ดูว่าความล่าช้าของอินพุตคืออะไร และเรียนรู้เทคนิคในการลดระยะเวลาดังกล่าวเพื่อให้โต้ตอบได้เร็วขึ้น
การโต้ตอบบนเว็บเป็นสิ่งที่ซับซ้อน โดยมีกิจกรรมทุกประเภทที่เกิดขึ้นในเบราว์เซอร์เป็นแรงขับเคลื่อนให้เกิดการโต้ตอบ แต่สิ่งที่เหมือนกันคือ อินพุตเหล่านี้จะมีความล่าช้าในการป้อนข้อมูลก่อนที่การเรียกกลับของเหตุการณ์จะเริ่มทำงาน ในคู่มือนี้ คุณจะได้เรียนรู้ว่าความล่าช้าในการป้อนข้อมูลคืออะไร และคุณจะทำอะไรได้บ้างเพื่อลดความล่าช้าเพื่อให้การโต้ตอบของเว็บไซต์ทำงานได้เร็วขึ้น
ความล่าช้าในการป้อนข้อมูลคืออะไร
ความล่าช้าของอินพุตคือระยะเวลาที่เริ่มต้นนับจากที่ผู้ใช้โต้ตอบกับหน้าเว็บเป็นครั้งแรก เช่น การแตะบนหน้าจอ การคลิกเมาส์ หรือการกดแป้น ไปจนถึงตอนที่เหตุการณ์ Callback ของการโต้ตอบเริ่มทำงาน การโต้ตอบทุกครั้งเริ่มต้นด้วยความล่าช้าในการป้อนข้อมูลเป็นระยะเวลาหนึ่ง
![การแสดงภาพความล่าช้าของอินพุตที่ง่ายขึ้น ทางด้านซ้ายมีภาพลายเส้นรูปเคอร์เซอร์เมาส์ที่มีดาวกระจายอยู่ด้านหลัง ซึ่งแสดงถึงการเริ่มการโต้ตอบ ทางด้านขวาคือภาพลายเส้นรูปฟันเฟือง ซึ่งแสดงถึงเวลาที่เครื่องจัดการเหตุการณ์ของการโต้ตอบเริ่มทำงาน ช่องว่างระหว่างเสียงจะแสดงเป็นความล่าช้าของอินพุตด้วยวงเล็บปีกกา](https://web.dev/static/articles/optimize-input-delay/image/a-simplified-visualizatio-d1514b424d9ec.png?authuser=2&hl=th)
ความล่าช้าของอินพุตบางส่วนหลีกเลี่ยงไม่ได้ เพราะระบบปฏิบัติการจะต้องใช้เวลาสักระยะหนึ่งในการจดจำเหตุการณ์อินพุตและส่งไปยังเบราว์เซอร์ อย่างไรก็ตาม ความล่าช้าของอินพุตส่วนนั้นมักจะไม่สามารถสังเกตได้ และมีเหตุการณ์อื่นๆ เกิดขึ้นในหน้านั้นเองที่อาจทำให้การป้อนข้อมูลล่าช้าพอที่จะทำให้เกิดปัญหาได้
ข้อควรพิจารณาเกี่ยวกับความล่าช้าในการป้อนข้อมูล
โดยทั่วไปแล้ว คุณควรทำให้ทุกส่วนของการโต้ตอบสั้นที่สุดเท่าที่จะเป็นไปได้เพื่อให้เว็บไซต์ของคุณมีโอกาสบรรลุระดับ "ดี" ของเมตริก Interaction to Next Paint (INP) เกณฑ์โดยไม่คำนึงถึงอุปกรณ์ของผู้ใช้ การตรวจสอบความล่าช้าของอินพุตเป็นเพียงส่วนหนึ่งของการผ่านเกณฑ์ดังกล่าว
ดังนั้น คุณจึงต้องพยายามทำให้อินพุตมีความล่าช้าน้อยที่สุดเท่าที่จะเป็นไปได้เพื่อให้เป็นไปตาม "ดี" ของ INP อย่างไรก็ตาม คุณควรทราบ คุณไม่สามารถคาดหวังที่จะขจัดความล่าช้าในการป้อนข้อมูลอย่างสิ้นเชิง ตราบใดที่คุณหลีกเลี่ยงการทำงานของเทรดหลักมากเกินไปขณะที่ผู้ใช้พยายามโต้ตอบกับหน้าเว็บ ความล่าช้าของอินพุตควรจะต่ำพอที่จะหลีกเลี่ยงปัญหา
วิธีลดความล่าช้าของอินพุต
ดังที่ได้กล่าวไว้ก่อนหน้านี้ ผู้ใช้ไม่สามารถหลีกเลี่ยงความล่าช้าในการป้อนข้อมูลได้ แต่ในทางกลับกัน ความล่าช้าในการป้อนข้อมูลบางอย่างก็สามารถหลีกเลี่ยงได้ หากคุณประสบปัญหาความล่าช้าในการป้อนข้อมูลเป็นเวลานาน โปรดทำดังนี้
หลีกเลี่ยงตัวจับเวลาที่เกิดซ้ำที่ทําให้เทรดหลักทำงานบ่อยเกินไป
มีฟังก์ชันตัวจับเวลาที่ใช้กันโดยทั่วไปอยู่ 2 รายการใน JavaScript ที่อาจส่งผลต่อความล่าช้าของอินพุต ได้แก่ setTimeout
และ setInterval
ความแตกต่างระหว่างทั้ง 2 ฟีเจอร์คือ setTimeout
จะกำหนดเวลาให้การติดต่อกลับหลังจากเวลาที่ระบุ ในทางกลับกัน setInterval
จะกำหนดเวลา Callback ให้ทำงานทุกๆ n มิลลิวินาทีตลอดอายุ หรือจนกว่าตัวจับเวลาจะหยุดด้วย clearInterval
setTimeout
จะไม่เป็นปัญหาในตัวมันเอง อันที่จริงก็มีประโยชน์ในการหลีกเลี่ยงงานที่ใช้เวลานานได้ อย่างไรก็ตาม ขึ้นอยู่กับเวลาที่การหมดเวลาเกิดขึ้น และผู้ใช้พยายามที่จะโต้ตอบกับหน้าเว็บเมื่อการเรียกกลับการหมดเวลาทำงานหรือไม่
นอกจากนี้ setTimeout
ยังเรียกใช้แบบวนซ้ำหรือที่เกิดซ้ำได้ ซึ่งจะทำงานคล้ายกับ setInterval
มากกว่า แต่ก็ไม่ควรกำหนดเวลาการทำซ้ำครั้งถัดไปจนกว่ารายการก่อนหน้าจะเสร็จสมบูรณ์ แม้ว่าการดำเนินการนี้จะทําให้การวนซ้ำแสดงผลต่อเทรดหลักทุกครั้งที่มีการเรียก setTimeout
แต่คุณควรระมัดระวังไม่ให้การเรียกกลับทำงานมากเกินไป
setInterval
เรียกใช้ Callback ในช่วงเวลาหนึ่ง จึงมีแนวโน้มที่จะขัดขวางการโต้ตอบได้มากกว่า นั่นก็เพราะว่าเป็นการเรียก setTimeout
แบบครั้งเดียวที่อาจเข้ามาขัดขวางการโต้ตอบของผู้ใช้ แต่ลักษณะการทำงานที่เกิดซ้ำของ setInterval
นั้น ทำให้มีแนวโน้มมากขึ้นที่ว่า setInterval
จะจะขัดขวางการโต้ตอบ ซึ่งจะเพิ่มความล่าช้าในการป้อนข้อมูลของการโต้ตอบ
![ภาพหน้าจอของเครื่องมือสร้างโปรไฟล์ประสิทธิภาพใน Chrome DevTools ที่แสดงความล่าช้าของอินพุต งานที่ฟังก์ชันตัวจับเวลาเริ่มทำงานจะเกิดขึ้นก่อนที่ผู้ใช้จะเริ่มการโต้ตอบการคลิก อย่างไรก็ตาม ตัวจับเวลาจะขยายการหน่วงเวลาอินพุต ทำให้การเรียกกลับของเหตุการณ์ของการโต้ตอบทำงานล่าช้ากว่าปกติ](https://web.dev/static/articles/optimize-input-delay/image/a-screenshot-the-perform-0955d1c357d1f.png?authuser=2&hl=th)
setInterval
ก่อนหน้าซึ่งมีส่วนทำให้การป้อนข้อมูลล่าช้าตามที่แสดงให้เห็นในแผงประสิทธิภาพของเครื่องมือสำหรับนักพัฒนาเว็บใน Chrome ความล่าช้าของอินพุตที่เพิ่มเข้ามาจะทำให้การเรียกกลับของเหตุการณ์สำหรับการโต้ตอบนั้นทำงานช้ากว่าที่ควรจะเป็น
หากตัวจับเวลาอยู่ในโค้ดของบุคคลที่หนึ่ง คุณจะควบคุมตัวจับเวลาได้ ประเมินว่าคุณต้องการความช่วยเหลือเป็นพิเศษ หรือพยายามอย่างเต็มที่เพื่อลดงานให้เหลือน้อยที่สุด แต่ตัวจับเวลาในสคริปต์ของบุคคลที่สามจะเป็นคนละเรื่องกัน คุณมักจะไม่สามารถควบคุมการทำงานของสคริปต์ของบุคคลที่สาม และแก้ไขปัญหาด้านประสิทธิภาพในโค้ดของบุคคลที่สามมักเกี่ยวข้องกับการทำงานร่วมกับผู้มีส่วนเกี่ยวข้องเพื่อพิจารณาว่าสคริปต์ของบุคคลที่สามจำเป็นต้องใช้หรือไม่ และหากใช่ ให้ติดต่อกับผู้ให้บริการสคริปต์บุคคลที่สามเพื่อพิจารณาถึงสิ่งที่ทำได้เพื่อแก้ไขปัญหาด้านประสิทธิภาพที่อาจเกิดในเว็บไซต์ของคุณ
หลีกเลี่ยงงานที่ใช้เวลานาน
วิธีหนึ่งที่จะช่วยลดความล่าช้าในการป้อนข้อมูลได้คือการหลีกเลี่ยงงานที่ใช้เวลานาน เมื่อคุณมีงานในเทรดหลักมากเกินไปซึ่งบล็อกเทรดหลักระหว่างการโต้ตอบ ชุดข้อความดังกล่าวจะทำให้อินพุตล่าช้าก่อนที่งานยาวๆ จะมีโอกาสเสร็จสิ้น
![การแสดงภาพระยะเวลาที่งานต่างๆ ขยายความล่าช้าในการป้อนข้อมูล ที่ด้านบน การโต้ตอบจะเกิดขึ้นไม่นานหลังจากงานที่ใช้เวลานานๆ งานเดียว ทำให้เกิดความล่าช้าในการป้อนข้อมูลที่สำคัญซึ่งทำให้ Callback ของเหตุการณ์ทำงานช้ากว่าที่ควรมาก ที่ด้านล่าง การโต้ตอบจะเกิดขึ้นในเวลาไล่เลี่ยกัน แต่งานที่ใช้เวลานานจะถูกแบ่งออกเป็นงานย่อยๆ หลายงานโดยการทำให้เกิด ทำให้การเรียกกลับของเหตุการณ์ของการโต้ตอบทำงานเร็วขึ้นมาก](https://web.dev/static/articles/optimize-input-delay/image/a-visualization-how-long-af65d3963b8fb.png?authuser=2&hl=th)
นอกจากจะลดปริมาณงานที่ทำในแล้ว และคุณควรพยายามทำงานให้น้อยที่สุดในชุดข้อความหลักเสมอ คุณยังปรับปรุงการตอบสนองต่อข้อมูลจากผู้ใช้ได้โดยแบ่งงานที่ใช้เวลานาน
โปรดระวังการโต้ตอบทับซ้อนกัน
ส่วนที่ท้าทายเป็นพิเศษในการเพิ่มประสิทธิภาพ INP อาจเป็นได้หากคุณมีการโต้ตอบที่ทับซ้อนกัน การโต้ตอบทับซ้อนกันหมายความว่าหลังจากที่คุณโต้ตอบกับองค์ประกอบหนึ่งแล้ว คุณจะมีการโต้ตอบอีกครั้งกับหน้าเว็บก่อนที่การโต้ตอบครั้งแรกจะมีโอกาสได้แสดงเฟรมถัดไป
![การแสดงภาพเมื่องานต่างๆ อาจทับซ้อนกันเพื่อทำให้การป้อนข้อมูลล่าช้าเป็นเวลานาน ในภาพนี้ การโต้ตอบแบบคลิกซ้อนทับกับการโต้ตอบคีย์ดาวน์ เพื่อเพิ่มความล่าช้าของอินพุตสําหรับการโต้ตอบคีย์ดาวน์](https://web.dev/static/articles/optimize-input-delay/image/a-depiction-when-tasks-8c6449133de24.png?authuser=2&hl=th)
แหล่งที่มาของการโต้ตอบที่ซ้อนทับอาจเป็นเรื่องง่ายจากการที่ผู้ใช้มีการโต้ตอบหลายครั้งในช่วงเวลาสั้นๆ ข้อผิดพลาดนี้อาจเกิดขึ้นเมื่อผู้ใช้พิมพ์ในช่องของฟอร์ม ซึ่งเป็นที่ที่เกิดการโต้ตอบกับแป้นพิมพ์จำนวนมากในระยะเวลาสั้นๆ หากงานในเหตุการณ์สำคัญมีราคาสูงเป็นพิเศษ เช่น ในกรณีทั่วไปของช่องการเติมข้อความอัตโนมัติที่มีการส่งคำขอของเครือข่ายไปยังแบ็กเอนด์ คุณมี 2 ตัวเลือกดังต่อไปนี้
- พิจารณาการดีเบานซ์อินพุตเพื่อจำกัดจํานวนครั้งที่จะเรียกใช้ Callback ของเหตุการณ์ในระยะเวลาที่กำหนด
- ใช้
AbortController
เพื่อยกเลิกคำขอfetch
ขาออกเพื่อไม่ให้เทรดหลักทำงานที่คับคั่งเมื่อต้องจัดการ Callback ของfetch
หมายเหตุ: พร็อพเพอร์ตี้signal
ของอินสแตนซ์AbortController
ใช้เพื่อล้มเลิกเหตุการณ์ได้ด้วย
อีกสาเหตุหนึ่งที่ทำให้อินพุตล่าช้าเนื่องจากการโต้ตอบทับซ้อนกันอาจเป็นภาพเคลื่อนไหวราคาแพง โดยเฉพาะอย่างยิ่ง ภาพเคลื่อนไหวใน JavaScript อาจเริ่มการเรียกใช้ requestAnimationFrame
หลายครั้ง ซึ่งอาจขัดขวางการโต้ตอบของผู้ใช้ วิธีหลีกเลี่ยงปัญหานี้คือใช้ภาพเคลื่อนไหว CSS ทุกครั้งที่ทำได้เพื่อหลีกเลี่ยงการต่อคิวเฟรมภาพเคลื่อนไหวราคาแพง แต่หากทำเช่นนี้ ให้หลีกเลี่ยงภาพเคลื่อนไหวที่ไม่ได้ทำการ Composite เพื่อให้ภาพเคลื่อนไหวทำงานบนเทรด GPU และเทรดคอมโพสิตเป็นหลัก ไม่ใช่บนเทรดหลัก
บทสรุป
แม้ว่าความล่าช้าในการป้อนข้อมูลอาจไม่ได้แสดงเวลาส่วนใหญ่ของการโต้ตอบของคุณ แต่คุณควรเข้าใจว่าการโต้ตอบทุกส่วนของการโต้ตอบต้องใช้เวลาที่คุณสามารถลดระยะเวลาได้ หากสังเกตการหน่วงเวลาการป้อนข้อมูลที่ยาว คุณก็มีโอกาสที่จะลดระยะเวลานี้ได้ การหลีกเลี่ยงการเรียกกลับตัวจับเวลาที่เกิดซ้ำ การแบ่งงานที่ใช้เวลานาน และการตระหนักถึงการโต้ตอบที่ซ้อนทับกันที่อาจเกิดขึ้น ล้วนช่วยลดความล่าช้าในการป้อนข้อมูลได้ ซึ่งส่งผลให้ผู้ใช้เว็บไซต์มีการโต้ตอบที่รวดเร็วขึ้น
รูปภาพหลักจาก Unsplash โดย Erik Mclean