Codelab: โหลดเนื้อหาที่สำคัญไว้ล่วงหน้าเพื่อปรับปรุงความเร็วในการโหลด

ฮูเซน จอร์เดห์
ฮูสเซน จอร์เดห์

ใน Codelab นี้ ประสิทธิภาพของหน้าเว็บต่อไปนี้ได้รับการปรับปรุงให้ดีขึ้นโดยการโหลดทรัพยากร 2-3 รายการล่วงหน้าและดึงข้อมูลล่วงหน้า

ภาพหน้าจอของแอป

วัดระยะทาง

ก่อนอื่นให้วัดประสิทธิภาพของเว็บไซต์ก่อนที่จะเพิ่มการเพิ่มประสิทธิภาพ

  • หากต้องการดูตัวอย่างเว็บไซต์ ให้กดดูแอป แล้วกดเต็มหน้าจอ เต็มหน้าจอ

เรียกใช้การตรวจสอบประสิทธิภาพของ Lighthouse (Lighthouse > Options > Performance) ใน Glitch เวอร์ชันสด (ดูค้นพบโอกาสด้านประสิทธิภาพด้วย Lighthouse)

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 เป็นเนื้อหาสำคัญที่จำเป็นทันทีที่โหลดหน้าเว็บ สำหรับไฟล์สำคัญอย่างทรัพยากรนี้ที่มีการดึงข้อมูลล่าช้าในแอปพลิเคชัน ให้ใช้แท็กโหลดลิงก์ล่วงหน้าเพื่อแจ้งให้เบราว์เซอร์ดาวน์โหลดเร็วขึ้นด้วยการเพิ่มองค์ประกอบลิงก์ในส่วนหัวของเอกสาร

เพิ่มแท็กโหลดล่วงหน้าสำหรับแอปพลิเคชันนี้:

<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 จะแสดงคำเตือนในแผงคอนโซลเมื่อหน้าไม่ได้ใช้ทรัพยากรที่โหลดไว้ล่วงหน้าภายใน 2-3 วินาทีหลังจากที่โหลดแล้ว

คำเตือนการโหลดล่วงหน้าในคอนโซล

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

<head>
  <!-- ... -->
  <link rel="preload" href="main.css" as="style">
  <link rel="preload" href="details.css" as="style">
</head>

ดูรายการทรัพยากรทุกประเภทที่ดึงข้อมูลได้พร้อมกับค่าที่ถูกต้องที่ควรใช้สำหรับแอตทริบิวต์ as ได้ที่บทความ MN เกี่ยวกับการโหลดล่วงหน้า

โหลดทรัพยากรในอนาคตล่วงหน้า

การดึงข้อมูลล่วงหน้าเป็นอีกหนึ่งคำแนะนำเบราว์เซอร์ที่สามารถใช้สร้างคำขอเนื้อหาที่ใช้สำหรับเส้นทางการนำทางอื่น แต่มีลำดับความสำคัญต่ำกว่าเนื้อหาสำคัญอื่นๆ ที่จำเป็นสำหรับหน้าปัจจุบัน

ในเว็บไซต์นี้ การคลิกที่รูปภาพจะนำคุณไปยังเส้นทาง details/ แยกต่างหาก

เส้นทางรายละเอียด

ไฟล์ CSS ที่แยกต่างหากคือ details.css จะมีสไตล์ทั้งหมดที่จำเป็นสำหรับหน้าธรรมดานี้ เพิ่มองค์ประกอบของลิงก์ลงใน index.html เพื่อดึงข้อมูลแหล่งข้อมูลนี้ล่วงหน้า

<head>
  <!-- ... -->
  <link rel="prefetch" href="details.css">
</head>

หากต้องการทำความเข้าใจว่าการดำเนินการนี้เรียกใช้คำขอไฟล์อย่างไร ให้เปิดแผงเครือข่ายในเครื่องมือสำหรับนักพัฒนาเว็บ แล้วยกเลิกการเลือกตัวเลือกปิดใช้แคช

ปิดใช้แคชในเครื่องมือสำหรับนักพัฒนาเว็บใน Chrome

โหลดแอปพลิเคชันซ้ำและสังเกตคำขอที่มีลำดับความสำคัญต่ำมากสำหรับ details.css หลังจากดึงข้อมูลไฟล์อื่นๆ ทั้งหมดแล้ว

แผงเครือข่ายที่มีทรัพยากรที่ดึงข้อมูลล่วงหน้า

เมื่อเปิดเครื่องมือสำหรับนักพัฒนาเว็บแล้ว ให้คลิกรูปภาพในเว็บไซต์เพื่อไปที่หน้า details เนื่องจากมีการใช้องค์ประกอบลิงก์ใน details.html เพื่อดึงข้อมูล details.css ระบบจึงสร้างคำขอสำหรับทรัพยากรตามที่คาดไว้

คำขอเครือข่ายของหน้ารายละเอียด

คลิกคำขอเครือข่าย details.css ในเครื่องมือสำหรับนักพัฒนาเว็บเพื่อดูรายละเอียด คุณจะสังเกตเห็นว่าไฟล์ถูกดึงมาจากดิสก์แคชของเบราว์เซอร์

ดึงคำขอรายละเอียดจากแคชดิสก์แล้ว

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

การโหลดล่วงหน้าและการดึงข้อมูลล่วงหน้าด้วย Webpack

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

แอป Magic Sorter ที่สาธิตการแยกโค้ด

คุณสามารถเข้าถึงกลิทช์สำหรับแอปพลิเคชันนี้ที่นี่

บล็อกโค้ดต่อไปนี้ที่อยู่ใน 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 จะแทรกแท็กการดึงข้อมูลล่วงหน้าสำหรับทรัพยากรลงในส่วนหัวของเอกสาร ซึ่งดูได้ในแผงองค์ประกอบ ในเครื่องมือสำหรับนักพัฒนาเว็บ

แผงองค์ประกอบที่มีแท็กการดึงข้อมูลล่วงหน้า

จากการสังเกตคำขอในแผงเครือข่ายยังแสดงให้เห็นว่าระบบดึงข้อมูลส่วนนี้โดยมีลำดับความสำคัญต่ำหลังจากมีการขอทรัพยากรอื่นๆ ทั้งหมดแล้ว

แผงเครือข่ายที่มีคำขอที่ดึงข้อมูลล่วงหน้า

แม้ว่าการดึงข้อมูลล่วงหน้าจะเหมาะสมกว่าสำหรับกรณีการใช้งานนี้ แต่ Webpack ยังรองรับการโหลดกลุ่มที่นำเข้าแบบไดนามิกไว้ล่วงหน้าด้วย

import(/* webpackPreload: true */ 'module')

บทสรุป

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

สรุปได้ดังนี้

  • ใช้การโหลดล่วงหน้าสำหรับทรัพยากรที่ค้นพบล่าช้า แต่สำคัญอย่างยิ่งต่อหน้าปัจจุบัน
  • ใช้การดึงข้อมูลล่วงหน้าสำหรับทรัพยากรที่จำเป็นสำหรับเส้นทางการนำทางหรือการดำเนินการของผู้ใช้ในอนาคต

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

หากคุณต้องการข้อมูลเพิ่มเติมเกี่ยวกับแง่มุมที่เฉพาะเจาะจงว่าการโหลดล่วงหน้าและการดึงข้อมูลล่วงหน้าจะส่งผลต่อหน้าเว็บอย่างไร โปรดอ่านบทความต่อไปนี้