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

เมื่อคุณเปิดหน้าเว็บ เบราว์เซอร์จะขอเอกสาร HTML จากเซิร์ฟเวอร์ แยกวิเคราะห์เนื้อหา และส่งคำขอแยกต่างหากสำหรับทรัพยากรที่อ้างอิง ในฐานะนักพัฒนาซอฟต์แวร์ คุณทราบอยู่แล้วเกี่ยวกับทรัพยากรทั้งหมดที่หน้าเว็บต้องการ และทรัพยากรใดที่สำคัญที่สุด โดยคุณสามารถใช้ความรู้ดังกล่าวเพื่อขอทรัพยากรที่สำคัญล่วงหน้าและเร่งกระบวนการโหลด โพสต์นี้อธิบายวิธีดำเนินการดังกล่าวด้วย <link rel="preload">

วิธีการทำงานของการโหลดล่วงหน้า

การโหลดล่วงหน้าเหมาะที่สุดสำหรับทรัพยากรที่เบราว์เซอร์มักค้นพบล่าช้า

ภาพหน้าจอแสดงแผงเครือข่ายเครื่องมือสำหรับนักพัฒนาเว็บใน Chrome
ในตัวอย่างนี้ แบบอักษร Pacifico ได้รับการกำหนดในสไตล์ชีตด้วยกฎ @font-face เบราว์เซอร์จะโหลดไฟล์แบบอักษรหลังจากที่ดาวน์โหลดและแยกวิเคราะห์สไตล์ชีตแล้วเท่านั้น

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

ภาพหน้าจอแผง Chrome DevTools Network หลังจากใช้การโหลดล่วงหน้า
ในตัวอย่างนี้ ระบบจะโหลดแบบอักษร Pacifico ไว้ล่วงหน้า การดาวน์โหลดจึงเกิดขึ้นพร้อมกันกับสไตล์ชีต

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

การตรวจสอบคำขอคีย์การโหลดล่วงหน้าของ Lighthouse

คุณโหลดทรัพยากรล่วงหน้าได้โดยเพิ่มแท็ก <link> ที่มี rel="preload" ที่ส่วนหัวของเอกสาร HTML ดังนี้

<link rel="preload" as="script" href="critical.js">

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

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

การโหลดล่วงหน้าที่ไม่ได้ใช้จะทำให้ระบบแสดงคำเตือน Console ใน Chrome หลังจากเหตุการณ์ load ประมาณ 3 วินาที

คำเตือนของคอนโซลเครื่องมือสำหรับนักพัฒนาเว็บใน Chrome เกี่ยวกับทรัพยากรที่โหลดไว้ล่วงหน้าที่ไม่ได้ใช้

กรณีการใช้งาน

การโหลดทรัพยากรล่วงหน้าที่กำหนดไว้ใน CSS

ระบบจะไม่ค้นพบแบบอักษรที่กำหนดด้วยกฎ @font-face หรือภาพพื้นหลังที่กำหนดในไฟล์ CSS จนกว่าเบราว์เซอร์จะดาวน์โหลดและแยกวิเคราะห์ไฟล์ CSS เหล่านั้น การโหลดทรัพยากรเหล่านี้ล่วงหน้าช่วยให้มั่นใจได้ว่ามีการดึงข้อมูลทรัพยากรดังกล่าวก่อนที่ไฟล์ CSS จะดาวน์โหลด

กำลังโหลดไฟล์ CSS ล่วงหน้า

หากใช้แนวทาง CSS ที่สำคัญ ให้แบ่ง CSS เป็น 2 ส่วน CSS ที่สำคัญซึ่งจำเป็นสำหรับการแสดงผลเนื้อหาครึ่งหน้าบนจะอยู่ในบรรทัด <head> ของเอกสาร และ CSS ที่ไม่สำคัญมักจะโหลดด้วย JavaScript แบบ Lazy Loading การรอให้ JavaScript ทำงานก่อนโหลด CSS ที่ไม่สำคัญอาจทำให้การแสดงผลล่าช้าเมื่อผู้ใช้เลื่อนหน้าจอ ดังนั้นจึงควรใช้ <link rel="preload"> เพื่อเริ่มการดาวน์โหลดได้เร็วขึ้น

กำลังโหลดไฟล์ JavaScript ล่วงหน้า

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

วิธีใช้ rel=preload

วิธีที่ง่ายที่สุดในการนำ preload ไปใช้คือการเพิ่มแท็ก <link> ลงใน <head> ของเอกสาร ดังนี้

<head>
  <link rel="preload" as="script" href="critical.js">
</head>

การระบุแอตทริบิวต์ as จะช่วยให้เบราว์เซอร์ตั้งค่าลำดับความสำคัญของทรัพยากรที่ดึงข้อมูลล่วงหน้าได้ตามประเภท ตั้งค่าส่วนหัวที่ถูกต้อง และพิจารณาว่ามีทรัพยากรดังกล่าวในแคชแล้วหรือยัง ค่าที่ยอมรับสำหรับแอตทริบิวต์นี้ ได้แก่ script, style, font, image และอื่นๆ

ทรัพยากรบางประเภท เช่น แบบอักษร จะโหลดในโหมดไม่ระบุตัวตน สำหรับผู้ที่ต้องตั้งค่าแอตทริบิวต์ crossorigin ด้วย preload ให้ทำดังนี้

<link rel="preload" href="ComicSans.woff2" as="font" type="font/woff2" crossorigin>

องค์ประกอบ <link> ยังยอมรับแอตทริบิวต์ type ซึ่งมีประเภท MIME ของทรัพยากรที่ลิงก์ด้วย เบราว์เซอร์จะใช้ค่าของแอตทริบิวต์ type เพื่อให้ระบบโหลดทรัพยากรล่วงหน้าเฉพาะในกรณีที่รองรับไฟล์ประเภทนั้นๆ หากเบราว์เซอร์ไม่รองรับประเภททรัพยากรที่ระบุ เบราว์เซอร์จะไม่สนใจ <link rel="preload">

คุณยังโหลดทรัพยากรทุกประเภทล่วงหน้าผ่านส่วนหัว HTTP Link ได้ด้วย โดยทำดังนี้

Link: </css/style.css>; rel="preload"; as="style"

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

กำลังโหลดโมดูล JavaScript ด้วย Webpack ล่วงหน้า

หากคุณใช้ Bundler โมดูลที่สร้างไฟล์บิลด์ของแอปพลิเคชัน คุณต้องตรวจสอบว่าโปรแกรมดังกล่าวรองรับการแทรกแท็กโหลดล่วงหน้าหรือไม่ webpack เวอร์ชัน 4.6.0 ขึ้นไปรองรับการโหลดล่วงหน้าผ่านการใช้ความคิดเห็นมหัศจรรย์ภายใน import() ดังนี้

import(_/* webpackPreload: true */_ "CriticalChunk")

หากคุณใช้ Webpack เวอร์ชันเก่า ให้ใช้ปลั๊กอินของบุคคลที่สาม เช่น preload-webpack-plugin

ผลของการโหลดล่วงหน้าต่อ Core Web Vitals

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

Largest Contentful Paint (LCP)

การโหลดล่วงหน้ามีผลอย่างมากต่อ Largest Contentful Paint (LCP) สำหรับแบบอักษรและรูปภาพ เนื่องจากทั้งรูปภาพและโหนดข้อความสามารถใช้เป็นตัวเลือก LCP ได้ รูปภาพหลักและข้อความขนาดใหญ่ที่แสดงผลโดยใช้แบบอักษรของเว็บจะได้รับประโยชน์อย่างมากจากคำแนะนำการโหลดล่วงหน้าที่จัดวางตำแหน่งได้ดี และควรใช้เมื่อมีโอกาสแสดงเนื้อหาส่วนสำคัญเหล่านี้แก่ผู้ใช้ได้เร็วขึ้น

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

แต่ให้มุ่งเน้นไปที่ทรัพยากรมูลค่าสูง 2-3 รายการที่คุณทราบว่าจะได้ประโยชน์จากการโหลดล่วงหน้าที่มีให้เป็นอย่างดีแทน เมื่อโหลดแบบอักษรล่วงหน้า โปรดตรวจสอบว่าคุณแสดงแบบอักษรในรูปแบบ WOFF 2.0 เพื่อลดเวลาที่ใช้ในการโหลดทรัพยากรลงมากที่สุด เนื่องจาก WOFF 2.0 มีการรองรับเบราว์เซอร์ที่ยอดเยี่ยม การใช้รูปแบบที่เก่ากว่าอย่าง WOFF 1.0 หรือ TrueType (TTF) จะทำให้ LCP ล่าช้าหากตัวเลือก LCP เป็นโหนดข้อความ

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

Cumulative Layout Shift (CLS)

Cumulative Layout Shift (CLS) เป็นเมตริกที่สำคัญมากสำหรับแบบอักษรในเว็บ และ CLS มีการโต้ตอบที่สำคัญกับแบบอักษรของเว็บที่ใช้พร็อพเพอร์ตี้ CSS ของ font-display เพื่อจัดการวิธีโหลดแบบอักษร หากต้องการลดการเปลี่ยนแปลงของเลย์เอาต์ที่เกี่ยวข้องกับแบบอักษรบนเว็บ ให้พิจารณากลยุทธ์ต่อไปนี้

  1. โหลดแบบอักษรล่วงหน้าในขณะที่ใช้ค่า block เริ่มต้นสำหรับ font-display นี่เป็นการสร้างสมดุลที่ละเอียดอ่อน การบล็อกการแสดงแบบอักษรโดยไม่มีการสำรองอาจนับเป็นปัญหาด้านประสบการณ์ของผู้ใช้ การโหลดแบบอักษรด้วย font-display: block; จะช่วยลดการเปลี่ยนแปลงของเลย์เอาต์ที่เกี่ยวข้องกับแบบอักษรบนเว็บ ในทางกลับกัน คุณก็ยังคงต้องการให้ระบบโหลดแบบอักษรของเว็บเหล่านั้นโดยเร็วที่สุด หากแบบอักษรเหล่านั้นสำคัญต่อประสบการณ์ของผู้ใช้ การรวมการโหลดล่วงหน้ากับ font-display: block; อาจเป็นการบุกรุกที่ยอมรับได้
  2. โหลดแบบอักษรล่วงหน้าขณะใช้ค่า fallback สำหรับ font-display fallback เป็นการบุกรุกระหว่าง swap ถึง block เนื่องจากมีระยะเวลาการบล็อกที่สั้นมาก
  3. ใช้ค่า optional สำหรับ font-display โดยไม่ต้องโหลดล่วงหน้า หากแบบอักษรเว็บไม่สำคัญต่อประสบการณ์ของผู้ใช้ แต่ยังใช้เพื่อแสดงข้อความจำนวนมากในหน้าเว็บ ให้ลองใช้ค่า optional หากเกิดเหตุการณ์ที่ไม่พึงประสงค์ optional จะแสดงข้อความในหน้าเว็บเป็นแบบอักษรสำรองขณะที่โหลดแบบอักษรนั้นในเบื้องหลังสำหรับการนำทางถัดไป ผลสุทธิของเงื่อนไขเหล่านี้คือ CLS ที่ได้รับการปรับปรุง เนื่องจากแบบอักษรของระบบจะแสดงผลทันที ส่วนการโหลดหน้าเว็บที่ตามมาจะโหลดแบบอักษรทันทีโดยไม่มีการเปลี่ยนแปลงเลย์เอาต์

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

การโต้ตอบกับ Next Paint (INP)

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

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

บทสรุป

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