ในโค้ดแล็บนี้ ประสิทธิภาพของหน้าเว็บต่อไปนี้จะได้รับการปรับปรุงด้วยการโหลดทรัพยากรล่วงหน้าและดึงข้อมูลล่วงหน้า
วัดระยะทาง
ก่อนอื่นให้วัดประสิทธิภาพของเว็บไซต์ก่อนที่จะเพิ่มการเพิ่มประสิทธิภาพ
- หากต้องการดูตัวอย่างเว็บไซต์ ให้กดดูแอป แล้วกดเต็มหน้าจอ
เรียกใช้การตรวจสอบประสิทธิภาพของ Lighthouse (Lighthouse > ตัวเลือก > ประสิทธิภาพ) ใน Glitch เวอร์ชันที่เผยแพร่ (ดูค้นพบโอกาสในการปรับปรุงประสิทธิภาพด้วย Lighthouse ด้วย)
Lighthouse แสดงการตรวจสอบที่ไม่สําเร็จต่อไปนี้สําหรับทรัพยากรที่ดึงข้อมูลล่าช้า
- กดแป้น Control+Shift+J (หรือ Command+Option+J ใน Mac) เพื่อเปิดเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์
- คลิกแท็บเครือข่าย
ไฟล์ main.css
ไม่ได้ดึงข้อมูลโดยองค์ประกอบลิงก์ (<link>
) ที่วางไว้ในเอกสาร HTML แต่ไฟล์ JavaScript แยกต่างหากชื่อ fetch-css.js
จะแนบองค์ประกอบลิงก์กับ DOM หลังจากเหตุการณ์ window.onLoad
ซึ่งหมายความว่าระบบจะดึงข้อมูลไฟล์หลังจากเบราว์เซอร์แยกวิเคราะห์และดำเนินการกับไฟล์ JS เสร็จแล้วเท่านั้น ในทํานองเดียวกัน ระบบจะดึงข้อมูลแบบอักษรเว็บ (K2D.woff2
) ที่ระบุภายใน main.css
ก็ต่อเมื่อไฟล์ CSS ดาวน์โหลดเสร็จแล้วเท่านั้น
ห่วงโซ่คำขอที่สำคัญแสดงลำดับทรัพยากรที่เบราว์เซอร์จัดลําดับความสําคัญและดึงข้อมูล หน้าเว็บนี้มีลักษณะดังนี้
├─┬ / (initial HTML file)
└── fetch-css.js
└── main.css
└── K2D.woff2
เนื่องจากไฟล์ CSS อยู่ในระดับที่ 3 ของเชนคำขอ Lighthouse จึงระบุว่าเป็นทรัพยากรที่ค้นพบช้า
โหลดทรัพยากรสําคัญล่วงหน้า
ไฟล์ main.css
เป็นชิ้นงานสําคัญที่จําเป็นทันทีที่โหลดหน้าเว็บ สําหรับไฟล์สําคัญ เช่น ทรัพยากรนี้ที่ดึงข้อมูลในภายหลังในแอปพลิเคชัน ให้ใช้แท็กการโหลดลิงก์ล่วงหน้าเพื่อแจ้งให้เบราว์เซอร์ดาวน์โหลดไฟล์เร็วขึ้นด้วยการเพิ่มองค์ประกอบ Link ไว้ที่ส่วนหัวของเอกสาร
เพิ่มแท็กการโหลดล่วงหน้าสําหรับแอปพลิเคชันนี้
<head>
<!-- ... -->
<link rel="preload" href="main.css" as="style">
</head>
แอตทริบิวต์ as
ใช้เพื่อระบุประเภททรัพยากรที่ดึงข้อมูล และ as="style"
ใช้เพื่อโหลดไฟล์สไตล์ชีตล่วงหน้า
โหลดแอปพลิเคชันซ้ำและดูที่แผงเครือข่ายในเครื่องมือสำหรับนักพัฒนาเว็บ
สังเกตว่าเบราว์เซอร์ดึงข้อมูลไฟล์ CSS ก่อนที่ JavaScript ที่รับผิดชอบในการดึงข้อมูลจะแยกวิเคราะห์เสร็จสิ้น เมื่อใช้การโหลดล่วงหน้า เบราว์เซอร์จะรู้ว่าต้องดึงข้อมูลทรัพยากรล่วงหน้าโดยสมมติว่าทรัพยากรนั้นสําคัญต่อหน้าเว็บ
หากใช้ไม่ถูกต้อง การโหลดล่วงหน้าอาจส่งผลเสียต่อประสิทธิภาพโดยการส่งคําขอทรัพยากรที่ไม่จําเป็นซึ่งไม่ได้ใช้ ในแอปพลิเคชันนี้ details.css
คือไฟล์ CSS อื่นที่อยู่ในรูทของโปรเจ็กต์ แต่ใช้สำหรับ /details route
แยกต่างหาก หากต้องการแสดงตัวอย่างการใช้การโหลดล่วงหน้าอย่างไม่ถูกต้อง ให้เพิ่มคำแนะนำการโหลดล่วงหน้าสำหรับทรัพยากรนี้ด้วย
<head>
<!-- ... -->
<link rel="preload" href="main.css" as="style">
<link rel="preload" href="details.css" as="style">
</head>
โหลดแอปพลิเคชันซ้ำและดูที่แผงเครือข่าย
มีการส่งคําขอเพื่อดึงข้อมูล details.css
แม้ว่าหน้าเว็บจะไม่ได้ใช้ก็ตาม
Chrome จะแสดงคำเตือนในแผงคอนโซลเมื่อหน้าเว็บไม่ได้ใช้ทรัพยากรที่โหลดไว้ล่วงหน้าภายในไม่กี่วินาทีหลังจากที่โหลด
ใช้คำเตือนนี้เป็นตัวบ่งชี้ว่าคุณมีทรัพยากรที่โหลดไว้ล่วงหน้าซึ่งหน้าเว็บไม่ได้ใช้ทันทีหรือไม่ ตอนนี้คุณนำลิงก์การโหลดล่วงหน้าที่ไม่จำเป็นของหน้านี้ออกได้แล้ว
<head>
<!-- ... -->
<link rel="preload" href="main.css" as="style">
<link rel="preload" href="details.css" as="style">
</head>
ดูรายการทรัพยากรทุกประเภทที่ดึงข้อมูลได้พร้อมด้วยค่าที่ถูกต้องซึ่งควรใช้สำหรับแอตทริบิวต์ as
ได้ที่บทความ MDN เกี่ยวกับการโหลดล่วงหน้า
โหลดทรัพยากรในอนาคตล่วงหน้า
การเรียกข้อมูลล่วงหน้าเป็นคำแนะนำเบราว์เซอร์อีกรายการหนึ่งที่สามารถใช้เพื่อส่งคำขอสำหรับชิ้นงานที่ใช้สําหรับเส้นทางการนําทางอื่น แต่มีลําดับความสําคัญต่ำกว่าชิ้นงานสําคัญอื่นๆ ที่จําเป็นสําหรับหน้าปัจจุบัน
ในเว็บไซต์นี้ การคลิกรูปภาพจะนำคุณไปยังdetails/
เส้นทางแยกต่างหาก
ไฟล์ CSS แยกต่างหากชื่อ details.css
มีสไตล์ทั้งหมดที่จําเป็นสําหรับหน้าเว็บที่เรียบง่ายนี้ เพิ่มองค์ประกอบลิงก์ลงใน index.html
เพื่อเตรียมทรัพยากรนี้ล่วงหน้า
<head>
<!-- ... -->
<link rel="prefetch" href="details.css">
</head>
หากต้องการทำความเข้าใจว่าการดำเนินการนี้ทริกเกอร์คำขอไฟล์ได้อย่างไร ให้เปิดแผงเครือข่ายในเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์ และยกเลิกการเลือกตัวเลือกปิดใช้แคช
โหลดแอปพลิเคชันอีกครั้งและสังเกตว่ามีการส่งคำขอที่มีลำดับความสำคัญต่ำมากสำหรับ details.css
อย่างไรหลังจากที่ดึงข้อมูลไฟล์อื่นๆ ทั้งหมดแล้ว
เมื่อเครื่องมือสำหรับนักพัฒนาเว็บเปิดอยู่ ให้คลิกรูปภาพในเว็บไซต์เพื่อไปยังหน้า details
เนื่องจากมีการใช้องค์ประกอบลิงก์ใน details.html
เพื่อดึงข้อมูล details.css
ระบบจึงส่งคําขอทรัพยากรตามที่คาดไว้
คลิกคำขอเครือข่าย details.css
ในเครื่องมือสำหรับนักพัฒนาเว็บเพื่อดูรายละเอียด คุณจะเห็นระบบดึงข้อมูลไฟล์จากแคชดิสก์ของเบราว์เซอร์
โดยการใช้ประโยชน์จากเวลาที่เบราว์เซอร์ไม่ได้ใช้งาน เทคโนโลยีนี้จึงส่งคําขอทรัพยากรที่จําเป็นสําหรับหน้าอื่นล่วงหน้า ซึ่งจะเร่งคำขอไปยังส่วนต่างๆ ในอนาคตโดยอนุญาตให้เบราว์เซอร์แคชชิ้นงานได้เร็วขึ้นและแสดงจากแคชเมื่อจำเป็น
การโหลดล่วงหน้าและการดึงข้อมูลล่วงหน้าด้วย webpack
โพสต์ลดเพย์โหลด JavaScript ด้วยการแยกโค้ดจะอธิบายการใช้การนําเข้าแบบไดนามิกเพื่อแยกกลุ่มออกเป็นหลายกลุ่ม ตัวอย่างนี้แสดงด้วยแอปพลิเคชันง่ายๆ ที่นําเข้าโมดูลจาก Lodash แบบไดนามิกเมื่อส่งแบบฟอร์ม
คุณสามารถเข้าถึงข้อบกพร่องของแอปพลิเคชันนี้ได้ที่นี่
บล็อกโค้ดต่อไปนี้ที่อยู่ใน src/index.js,
มีหน้าที่ในการนําเข้าเมธอดแบบไดนามิกเมื่อมีการคลิกปุ่ม
form.addEventListener("submit", e => {
e.preventDefault()
import('lodash.sortby')
.then(module => module.default)
.then(sortInput())
.catch(err => { alert(err) });
});
การแยกกลุ่มจะปรับปรุงเวลาในการโหลดหน้าเว็บด้วยการลดขนาดเริ่มต้นของกลุ่ม webpack เวอร์ชัน 4.6.0 รองรับการโหลดล่วงหน้าหรือโหลดข้อมูลล่วงหน้าของกลุ่มที่นําเข้าแบบไดนามิก โดยใช้แอปพลิเคชันนี้เป็นตัวอย่าง วิธีการ lodash
สามารถโหลดล่วงหน้าได้เมื่อเบราว์เซอร์ไม่มีการใช้งาน และเมื่อผู้ใช้กดปุ่ม ก็จะไม่มีการหน่วงเวลาในการดึงข้อมูล
ใช้พารามิเตอร์ความคิดเห็น webpackPrefetch
ที่เฉพาะเจาะจงภายในการนําเข้าแบบไดนามิกเพื่อเตรียมข้อมูลบางส่วนไว้ล่วงหน้า
ตัวอย่างลักษณะของแอปพลิเคชันนี้
form.addEventListener("submit", e => {
e.preventDefault()
import(/* webpackPrefetch: true */ 'lodash.sortby')
.then(module => module.default)
.then(sortInput())
.catch(err => { alert(err) });
});
เมื่อโหลดแอปพลิเคชันอีกครั้ง webpack จะแทรกแท็ก prefetch สําหรับทรัพยากรลงในส่วนหัวของเอกสาร ซึ่งจะแสดงในแผงองค์ประกอบในเครื่องมือสําหรับนักพัฒนาเว็บ
การสังเกตคําขอในแผงเครือข่ายยังแสดงให้เห็นด้วยว่ามีการดึงข้อมูลกลุ่มนี้โดยมีลําดับความสําคัญต่ำหลังจากที่มีการขอทรัพยากรอื่นๆ ทั้งหมดแล้ว
แม้ว่าการโหลดล่วงหน้าจะเหมาะสมกับกรณีการใช้งานนี้มากกว่า แต่ Webpack ยังรองรับการโหลดล่วงหน้าของกลุ่มที่นําเข้าแบบไดนามิกด้วย
import(/* webpackPreload: true */ 'module')
บทสรุป
เมื่อทำตามโค้ดแล็บนี้ คุณควรมีความเข้าใจที่ชัดเจนว่าการโหลดล่วงหน้าหรือโหลดเนื้อหาบางส่วนล่วงหน้าช่วยปรับปรุงประสบการณ์ของผู้ใช้เว็บไซต์ได้อย่างไร โปรดทราบว่าเทคนิคเหล่านี้ไม่ควรใช้กับทรัพยากรทุกรายการ และการใช้เทคนิคเหล่านี้อย่างไม่ถูกต้องอาจส่งผลเสียต่อประสิทธิภาพ ผลลัพธ์ที่ดีที่สุดจะเกิดขึ้นเมื่อมีการโหลดล่วงหน้าหรือโหลดล่วงหน้าแบบเลือกเฉพาะเท่านั้น
โดยสรุป
- ใช้การโหลดล่วงหน้าสำหรับทรัพยากรที่ค้นพบช้า แต่มีความสำคัญต่อหน้าปัจจุบัน
- ใช้การดึงข้อมูลล่วงหน้าสำหรับทรัพยากรที่จําเป็นสําหรับเส้นทางการนําทางหรือการดำเนินการของผู้ใช้ในอนาคต
ปัจจุบันเบราว์เซอร์บางรายการไม่รองรับทั้งการโหลดล่วงหน้าและการโหลดล่วงหน้า ซึ่งหมายความว่าผู้ใช้แอปพลิเคชันบางรายอาจไม่สังเกตเห็นการปรับปรุงประสิทธิภาพ
หากต้องการข้อมูลเพิ่มเติมเกี่ยวกับแง่มุมที่เฉพาะเจาะจงของผลกระทบที่การโหลดล่วงหน้าและการโหลดล่วงหน้ามีต่อหน้าเว็บ โปรดอ่านบทความต่อไปนี้