วิธีตอบสนองต่อการโต้ตอบของผู้ใช้ให้เร็วขึ้น
ฉันคลิกแล้วแต่ไม่มีอะไรเกิดขึ้น ทำไมฉันจึงโต้ตอบกับหน้านี้ไม่ได้ 😢
First Contentful Paint (FCP) และ Largest Contentful Paint (LCP) เป็นเมตริกทั้ง 2 รายการที่วัดระยะเวลาที่ใช้ในการสร้างเนื้อหา แสดงผล (ภาพ) บนหน้า แม้ว่าเวลาระบายสีจะมีความสำคัญ แต่จะไม่มีการบันทึกปริมาณโหลด การตอบสนอง: หรือความเร็วที่หน้าเว็บตอบสนองต่อการโต้ตอบของผู้ใช้
First Input Delay (FID) คือเมตริกของ Core Web Vitals ที่รวบรวม ความประทับใจแรกต่อการโต้ตอบและการตอบสนองของเว็บไซต์ วัดระยะเวลาตั้งแต่ตอนที่ผู้ใช้ โต้ตอบกับหน้าเว็บเป็นครั้งแรก ณ เวลาที่เบราว์เซอร์สามารถตอบสนองได้จริงๆ การโต้ตอบ FID เป็นเมตริกฟิลด์และไม่สามารถ ซึ่งจำลองขึ้น ในสภาพแวดล้อมของห้องทดลอง จำเป็นต้องมีการโต้ตอบของผู้ใช้จริงเพื่อวัด ความล่าช้าของการตอบกลับ
เพื่อช่วยคาดการณ์ FID ในห้องทดลอง เราได้ ขอแนะนำระยะเวลาทั้งหมดในการบล็อก (TBT) เมตริกทั้งสองจะวัดค่าที่ต่างกัน การเพิ่มขึ้นของ TBT มักจะสอดคล้องกับการเพิ่มขึ้นของ FID
สาเหตุหลักของการที่ FID ไม่ดีคือการใช้ JavaScript จำนวนมาก เพิ่มประสิทธิภาพวิธีการแยกวิเคราะห์ JavaScript คอมไพล์ และการดำเนินการในหน้าเว็บของคุณจะลด FID โดยตรง
การดำเนินการกับ JavaScript จำนวนมาก
เบราว์เซอร์ตอบสนองต่อข้อมูลส่วนใหญ่ของผู้ใช้ไม่ได้ขณะที่เรียกใช้ JavaScript ในเทรดหลัก กล่าวคือ เบราว์เซอร์ตอบสนองการโต้ตอบของผู้ใช้ไม่ได้ขณะที่เทรดหลักไม่ว่าง สิ่งที่ควรปรับปรุง
- แบ่งงานที่ใช้เวลานาน
- เพิ่มประสิทธิภาพหน้าเว็บเพื่อความพร้อมในการโต้ตอบ
- ใช้ Web Worker
- ลดเวลาในการดำเนินการกับ JavaScript
แบ่งงานที่ใช้เวลานาน
หากได้พยายามลดจำนวน JavaScript ที่โหลดในหน้าเดียวแล้ว ระบบจะสามารถ มีประโยชน์ในการแบ่งโค้ดที่ยาวเป็นงานแบบไม่พร้อมกันขนาดเล็ก
งานที่ใช้เวลานานคือระยะเวลาการดำเนินการของ JavaScript ที่ผู้ใช้อาจ พบว่า UI ไม่ตอบสนอง โค้ดใดๆ ที่บล็อกเทรดหลักเป็นเวลา 50 มิลลิวินาทีขึ้นไปสามารถ มีลักษณะเป็นงานที่ใช้เวลานาน งานที่ใช้เวลานานเป็นสัญญาณของ การขยาย JavaScript ที่อาจเกิดขึ้น (การโหลดและการดำเนินการมากกว่าที่ผู้ใช้อาจต้องการในขณะนี้) การแบ่งงานที่ใช้เวลานานจะช่วยลดความล่าช้าในการป้อนข้อมูลในเว็บไซต์ได้
![งานที่ใช้เวลานานในเครื่องมือสำหรับนักพัฒนาเว็บใน Chrome](https://web.dev/static/articles/optimize-fid/image/long-tasks-chrome-devtoo-490129b8a172d.png?authuser=19&hl=th)
FID ควรปรับปรุงให้ดีขึ้นอย่างเห็นได้ชัด เมื่อคุณใช้แนวทางปฏิบัติแนะนำ เช่น การแยกโค้ดและการแยกรายละเอียด งานที่ใช้เวลานาน แม้ว่า TBT ไม่ใช่เมตริกภาคสนาม แต่ก็มีประโยชน์สำหรับการตรวจสอบความคืบหน้าใน ซึ่งปรับปรุงทั้ง Time To Interactive (TTI) และ FID
เพิ่มประสิทธิภาพหน้าเว็บเพื่อความพร้อมในการโต้ตอบ
มีสาเหตุที่พบบ่อยหลายประการที่ทำให้คะแนน FID และ TBT ต่ำในเว็บแอปที่ต้องใช้ JavaScript:
การดำเนินการสคริปต์ของบุคคลที่หนึ่งอาจชะลอความพร้อมในการโต้ตอบ
- การขยายขนาด JavaScript การดำเนินการที่มาก และการแบ่งออกเป็นส่วนๆ ที่ไม่มีประสิทธิภาพจะทำให้ช้าลง สามารถตอบสนองต่อข้อมูลจากผู้ใช้และส่งผลต่อ FID, TBT และ TTI การโหลดโค้ดแบบโพรเกรสซีฟและ จะช่วยกระจายงานนี้และปรับปรุงความพร้อมในการโต้ตอบ
- แอปที่แสดงผลฝั่งเซิร์ฟเวอร์อาจดูเหมือนว่ากำลังระบายพิกเซลบนหน้าจอ อย่างรวดเร็ว แต่ระวังการโต้ตอบของผู้ใช้ถูกบล็อกโดยการเรียกใช้สคริปต์ขนาดใหญ่ (เช่น (re-hydration) เพื่อดึงข้อมูล Listener เหตุการณ์) ซึ่งอาจใช้เวลาหลายร้อยมิลลิวินาที บางครั้ง แม้แต่วินาที หากใช้การแยกโค้ดตามเส้นทาง ลองเปลี่ยนตรรกะมากขึ้น ฝั่งเซิร์ฟเวอร์หรือสร้างเนื้อหาเพิ่มเติมแบบคงที่ในช่วงเวลาบิลด์
ด้านล่างนี้คือคะแนน TBT ก่อนและหลังการเพิ่มประสิทธิภาพการโหลดสคริปต์ของบุคคลที่หนึ่ง แอปพลิเคชัน ย้ายข้อมูลการโหลดสคริปต์ที่มีต้นทุนสูง (และการดำเนินการ) สำหรับคอมโพเนนต์ที่ไม่จำเป็นออกจาก ผู้ใช้จึงโต้ตอบกับหน้าเว็บได้เร็วขึ้นมาก
การดึงข้อมูลอาจส่งผลต่อความพร้อมในการโต้ตอบได้หลายด้าน
- การรอตามลำดับขั้นของการดึงข้อมูลแบบต่อเรียง (เช่น JavaScript และการดึงข้อมูลสำหรับคอมโพเนนต์) ทำได้ ส่งผลต่อเวลาในการตอบสนองของการโต้ตอบ มีจุดประสงค์เพื่อลดการอาศัยการดึงข้อมูลแบบต่อเรียงกันให้เหลือน้อยที่สุด
- พื้นที่เก็บข้อมูลแบบอินไลน์ขนาดใหญ่อาจเร่งเวลาการแยกวิเคราะห์ HTML และส่งผลต่อทั้งการแสดงผลและการโต้ตอบ เมตริกต่างๆ ตั้งเป้าไปที่การลดปริมาณข้อมูลที่ต้องทำหลังการประมวลผลในฝั่งไคลเอ็นต์
การดำเนินการสคริปต์ของบุคคลที่สามอาจทำให้เวลาในการตอบสนองของการโต้ตอบล่าช้าด้วยเช่นกัน
- เว็บไซต์จำนวนมากมีแท็กจากบุคคลที่สามและการวิเคราะห์ ซึ่งทำให้เครือข่ายไม่ว่างและ ทำให้เทรดหลักไม่ตอบสนองเป็นระยะๆ ซึ่งจะส่งผลต่อเวลาในการตอบสนองของการโต้ตอบ สำรวจ การโหลดโค้ดของบุคคลที่สามแบบออนดีมานด์ (เช่น อาจไม่โหลดโฆษณาครึ่งหน้าล่างจนกว่า เลื่อนเข้าใกล้วิวพอร์ตมากขึ้น)
- ในบางกรณี สคริปต์ของบุคคลที่สามสามารถจองสคริปต์ของบุคคลที่หนึ่งไว้ชั่วคราวในแง่ของลำดับความสำคัญและ ในเทรดหลัก รวมถึงทำให้หน้าเว็บพร้อมโต้ตอบช้าลงด้วย ความพยายามที่จะ ให้จัดลำดับความสำคัญของการโหลดสิ่งที่คุณคิดว่ามีประโยชน์กับผู้ใช้เป็นอันดับแรก
ใช้ Web Worker
เทรดหลักที่ถูกบล็อกเป็นหนึ่งในสาเหตุหลักที่ทำให้อินพุตล่าช้า เว็บ ผู้ปฏิบัติงานทำให้เรียกใช้ JavaScript ได้ บนชุดข้อความที่พื้นหลังแล้ว การย้ายการดำเนินการที่ไม่ใช่ UI ไปยังเทรดผู้ปฏิบัติงานที่แยกต่างหากอาจลดจำนวนการดำเนินการหลัก เวลาในการบล็อกเทรด และปรับปรุง FID
ลองใช้ไลบรารีต่อไปนี้เพื่อให้ใช้ Web Worker บนไซต์ได้ง่ายขึ้น
- Comlink: ไลบรารีตัวช่วยที่จัดเรียง
postMessage
และทำให้ใช้งานง่ายขึ้น - Workway: เครื่องมือส่งออกผู้ปฏิบัติงานบนเว็บสำหรับจุดประสงค์ทั่วไป
- Workerize: ย้ายโมดูลไปยัง Web Worker
ลดเวลาในการดำเนินการกับ JavaScript
การจำกัดจำนวน JavaScript ในหน้าเว็บจะลดเวลาที่เบราว์เซอร์ต้องใช้ ในการเรียกใช้โค้ด JavaScript ซึ่งจะช่วยเร่งความเร็วที่เบราว์เซอร์สามารถเริ่มตอบสนอง การโต้ตอบของผู้ใช้
หากต้องการลดจำนวน JavaScript ที่ดำเนินการในหน้าเว็บ ให้ทำดังนี้
- เลื่อน JavaScript ที่ไม่ได้ใช้
- ลด Polyfill ที่ไม่ได้ใช้
เลื่อน JavaScript ที่ไม่ได้ใช้
โดยค่าเริ่มต้น JavaScript ทั้งหมดกำลังบล็อกการแสดงผลอยู่ เมื่อเบราว์เซอร์พบแท็กสคริปต์ที่ลิงก์ไปยัง ไฟล์ JavaScript ภายนอก จะต้องหยุดสิ่งที่กำลังทำไว้ชั่วคราว แล้วดาวน์โหลด แยกวิเคราะห์ คอมไพล์ และเรียกใช้ JavaScript นั้น ดังนั้น คุณควรโหลดเฉพาะโค้ดที่จำเป็นสำหรับหน้าเว็บหรือ ตอบสนองต่อข้อมูลจากผู้ใช้
แท็บความครอบคลุมใน Chrome เครื่องมือสำหรับนักพัฒนาเว็บจะบอกได้ว่าหน้าเว็บไม่ได้ใช้ JavaScript เท่าใด
วิธีลด JavaScript ที่ไม่ได้ใช้
- แบ่งโค้ดออกเป็นกลุ่มๆ
- เลื่อน JavaScript ที่ไม่สำคัญรวมถึงสคริปต์ของบุคคลที่สามโดยใช้
async
หรือdefer
การแยกโค้ดคือการแยกกลุ่ม JavaScript ขนาดใหญ่ชุดเดียวออกเป็นกลุ่มเล็กๆ ที่โหลดแบบมีเงื่อนไขได้ (หรือเรียกว่าการโหลดแบบ Lazy Loading) เบราว์เซอร์รุ่นใหม่ส่วนใหญ่รองรับไวยากรณ์การนำเข้าแบบไดนามิก ซึ่งช่วยให้ดึงข้อมูลโมดูลได้แบบออนดีมานด์
import('module.js').then((module) => {
// Do something with the module.
});
การนำเข้า JavaScript แบบไดนามิกเมื่อมีการโต้ตอบกับผู้ใช้บางประเภท (เช่น การเปลี่ยนเส้นทางหรือ เพื่อแสดงโมดัล) จะตรวจสอบว่าโค้ดที่ไม่ได้ใช้สำหรับการโหลดหน้าเว็บเริ่มต้นจะถูกดึงข้อมูลก็ต่อเมื่อ ที่จำเป็น
นอกเหนือจากการรองรับเบราว์เซอร์ทั่วไปแล้ว ไวยากรณ์การนำเข้าแบบไดนามิกยังใช้ได้ในบิลด์ต่างๆ ระบบต่างๆ
- หากใช้ Webpack ภาพรวม หรือ Parcel เป็น Bundler ของโมดูล ใช้ประโยชน์จาก การนำเข้าแบบไดนามิก
- เฟรมเวิร์กฝั่งไคลเอ็นต์ เช่น รีแอ็ก Angular และ ระบุVue ที่ช่วยให้โหลดแบบ Lazy Loading ได้ง่ายขึ้นในระดับคอมโพเนนต์
นอกจากการแยกโค้ดแล้ว ให้ใช้ async หรือ เลื่อนเวลาออกไปสำหรับสคริปต์ที่ไม่จำเป็นสำหรับ เส้นทางวิกฤติหรือเนื้อหาครึ่งหน้าบน
<script defer src="…"></script>
<script async src="…"></script>
สคริปต์ของบุคคลที่สามทั้งหมดควรโหลดด้วย defer
เว้นแต่จะมีเหตุผลที่เฉพาะเจาะจง
หรือ async
โดยค่าเริ่มต้น
ลด Polyfill ที่ไม่ได้ใช้
หากคุณเขียนโค้ดโดยใช้ไวยากรณ์ JavaScript ที่ทันสมัยและอ้างอิง API เบราว์เซอร์ที่ทันสมัย คุณจะ ต้องย้าย URL และใส่โพลีฟิลเพื่อให้ใช้ได้ในเบราว์เซอร์รุ่นเก่า
ข้อกังวลเรื่องประสิทธิภาพหลักๆ ประการหนึ่งเกี่ยวกับการรวม Polyfill และโค้ดที่เปลี่ยนรูปแบบแล้วในเว็บไซต์ของคุณคือ เบราว์เซอร์รุ่นใหม่ไม่ควรจะต้องดาวน์โหลดเบราว์เซอร์หากไม่มีการใช้งาน ลดการใช้ JavaScript ขนาดของแอป ให้ลดจำนวน Polyfill ที่ไม่ได้ใช้ให้ได้มากที่สุดเท่าที่จะเป็นไปได้ และจำกัดการใช้งาน สภาพแวดล้อมที่จำเป็น
วิธีเพิ่มประสิทธิภาพการใช้ Polyfill ในเว็บไซต์
- หากคุณใช้ Babel เป็นตัวเปลี่ยนรูปแบบ ให้ใช้
@babel/preset-env
เพื่อรวมเฉพาะ Polyfill ที่จำเป็นสำหรับเบราว์เซอร์ที่คุณวางแผนจะกำหนดเป้าหมาย สำหรับ Babel 7.9 ให้เปิดใช้ ตัวเลือกbugfixes
เพื่อลดขนาดลงอีก กับ Polyfill ที่ไม่จำเป็น ใช้รูปแบบโมดูล/ไม่มีโมดูลเพื่อส่ง 2 แพ็กเกจแยกกัน (
@babel/preset-env
ด้วย รองรับผ่านtarget.esmodules
)<script type="module" src="modern.js"></script> <script nomodule src="legacy.js" defer></script>
ฟีเจอร์ใหม่ๆ มากมายของ ECMAScript ที่คอมไพล์ด้วย Babel ได้รับการรองรับในสภาพแวดล้อมแล้ว ที่รองรับโมดูล JavaScript การทำเช่นนี้ช่วยให้คุณลดความซับซ้อนของกระบวนการตรวจสอบว่า เฉพาะโค้ดที่แปลงแล้วจะใช้สำหรับเบราว์เซอร์ที่ต้องใช้โค้ดนั้นจริงๆ เท่านั้น
เครื่องมือสำหรับนักพัฒนาซอฟต์แวร์
มีเครื่องมือหลายอย่างที่ใช้ในการวัดและแก้ไขข้อบกพร่อง FID ดังนี้
ไม่มี Lighthouse 6.0 รองรับ FID เนื่องจากเป็นเมตริกภาคสนาม อย่างไรก็ตาม การบล็อกทั้งหมด Time (TBT) ใช้เป็นพร็อกซีได้ การเพิ่มประสิทธิภาพที่ช่วยปรับปรุง TBT ควร และปรับปรุง FID ในด้านดังกล่าวด้วย
รายงานประสบการณ์ของผู้ใช้ Chrome ระบุค่า FID ตามจริงที่รวบรวมที่ระดับต้นทาง
ขอขอบคุณ Philip Walton, Kayce Basques, Ilya Grigorik และ Annie Sullivan ที่ร่วมรีวิว