เมื่อคุณเปิดหน้าเว็บ เบราว์เซอร์จะขอเอกสาร HTML จากเซิร์ฟเวอร์ แยกวิเคราะห์เนื้อหา และส่งคำขอแยกต่างหากสำหรับทรัพยากรที่อ้างอิง ในฐานะนักพัฒนาซอฟต์แวร์ คุณทราบอยู่แล้วเกี่ยวกับทรัพยากรทั้งหมดที่หน้าเว็บต้องการ และทรัพยากรใดที่สำคัญที่สุด โดยคุณสามารถใช้ความรู้ดังกล่าวเพื่อขอทรัพยากรที่สำคัญล่วงหน้าและเร่งกระบวนการโหลด โพสต์นี้อธิบายวิธีดำเนินการดังกล่าวด้วย <link rel="preload">
วิธีการทำงานของการโหลดล่วงหน้า
การโหลดล่วงหน้าเหมาะที่สุดสำหรับทรัพยากรที่เบราว์เซอร์มักค้นพบล่าช้า
การโหลดทรัพยากรบางรายการล่วงหน้าเป็นการบอกเบราว์เซอร์ว่าคุณต้องการดึงข้อมูลเร็วกว่าที่เบราว์เซอร์จะพบเนื่องจากคุณมั่นใจว่าหน้าปัจจุบันมีความสำคัญ
ห่วงโซ่คำขอที่สำคัญจะแสดงลำดับของทรัพยากรที่เบราว์เซอร์จัดลำดับความสำคัญและดึงมา Lighthouse ระบุว่าชิ้นงานอยู่ในระดับที่ 3 ของเชนนี้ว่ามีการค้นพบล่าช้า คุณสามารถใช้การตรวจสอบโหลดคำขอคีย์ล่วงหน้าเพื่อระบุทรัพยากรที่จะโหลดล่วงหน้า
คุณโหลดทรัพยากรล่วงหน้าได้โดยเพิ่มแท็ก <link>
ที่มี rel="preload"
ที่ส่วนหัวของเอกสาร HTML ดังนี้
<link rel="preload" as="script" href="critical.js">
เบราว์เซอร์จะแคชทรัพยากรที่โหลดไว้ล่วงหน้าเพื่อให้สามารถใช้งานได้ทันทีเมื่อต้องการ (ไม่มีการเรียกใช้สคริปต์หรือใช้สไตล์ชีต)
คำแนะนำเกี่ยวกับทรัพยากร เช่น preconnect
และ prefetch
จะทำงานเมื่อเบราว์เซอร์เห็นว่าเหมาะสม ในทางกลับกัน preload
เป็นสิ่งที่จำเป็นสำหรับเบราว์เซอร์ เบราว์เซอร์ที่ทันสมัยให้ความสำคัญกับทรัพยากรต่างๆ อยู่แล้ว ดังนั้นการใช้ preload
อย่างจำกัดและเฉพาะทรัพยากรที่สำคัญที่สุดโหลดไว้ล่วงหน้าเท่านั้น
การโหลดล่วงหน้าที่ไม่ได้ใช้จะทำให้ระบบแสดงคำเตือน Console ใน Chrome หลังจากเหตุการณ์ load
ประมาณ 3 วินาที
กรณีการใช้งาน
การโหลดทรัพยากรล่วงหน้าที่กำหนดไว้ใน 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
เพื่อจัดการวิธีโหลดแบบอักษร หากต้องการลดการเปลี่ยนแปลงของเลย์เอาต์ที่เกี่ยวข้องกับแบบอักษรบนเว็บ ให้พิจารณากลยุทธ์ต่อไปนี้
- โหลดแบบอักษรล่วงหน้าในขณะที่ใช้ค่า
block
เริ่มต้นสำหรับfont-display
นี่เป็นการสร้างสมดุลที่ละเอียดอ่อน การบล็อกการแสดงแบบอักษรโดยไม่มีการสำรองอาจนับเป็นปัญหาด้านประสบการณ์ของผู้ใช้ การโหลดแบบอักษรด้วยfont-display: block;
จะช่วยลดการเปลี่ยนแปลงของเลย์เอาต์ที่เกี่ยวข้องกับแบบอักษรบนเว็บ ในทางกลับกัน คุณก็ยังคงต้องการให้ระบบโหลดแบบอักษรของเว็บเหล่านั้นโดยเร็วที่สุด หากแบบอักษรเหล่านั้นสำคัญต่อประสบการณ์ของผู้ใช้ การรวมการโหลดล่วงหน้ากับfont-display: block;
อาจเป็นการบุกรุกที่ยอมรับได้ - โหลดแบบอักษรล่วงหน้าขณะใช้ค่า
fallback
สำหรับfont-display
fallback
เป็นการบุกรุกระหว่างswap
ถึงblock
เนื่องจากมีระยะเวลาการบล็อกที่สั้นมาก - ใช้ค่า
optional
สำหรับfont-display
โดยไม่ต้องโหลดล่วงหน้า หากแบบอักษรเว็บไม่สำคัญต่อประสบการณ์ของผู้ใช้ แต่ยังใช้เพื่อแสดงข้อความจำนวนมากในหน้าเว็บ ให้ลองใช้ค่าoptional
หากเกิดเหตุการณ์ที่ไม่พึงประสงค์optional
จะแสดงข้อความในหน้าเว็บเป็นแบบอักษรสำรองขณะที่โหลดแบบอักษรนั้นในเบื้องหลังสำหรับการนำทางถัดไป ผลสุทธิของเงื่อนไขเหล่านี้คือ CLS ที่ได้รับการปรับปรุง เนื่องจากแบบอักษรของระบบจะแสดงผลทันที ส่วนการโหลดหน้าเว็บที่ตามมาจะโหลดแบบอักษรทันทีโดยไม่มีการเปลี่ยนแปลงเลย์เอาต์
CLS เป็นเมตริกที่เพิ่มประสิทธิภาพได้ยากเมื่อพูดถึงแบบอักษรบนเว็บ และเช่นเคย ให้ทดลองใน lab แต่ไว้วางใจข้อมูลในช่อง เพื่อดูว่ากลยุทธ์การโหลดแบบอักษรช่วยปรับปรุง CLS หรือทำให้แย่ลง
การโต้ตอบกับ Next Paint (INP)
การโต้ตอบกับ Next Paint เป็นเมตริกที่วัดการตอบสนองต่อข้อมูลจากผู้ใช้ เนื่องจากสัดส่วนของการโต้ตอบสูงสุดบนเว็บนั้นขับเคลื่อนด้วย JavaScript การโหลด JavaScript ล่วงหน้าที่ขับเคลื่อนการโต้ตอบที่สำคัญอาจช่วยให้ INP ของหน้าเว็บลดลงได้ อย่างไรก็ตาม โปรดทราบว่าการโหลด JavaScript ล่วงหน้ามากเกินไปในช่วงเริ่มต้นอาจส่งผลเสียต่อการทำงานโดยไม่เจตนาได้หากมีทรัพยากรจำนวนมากแข่งขันกันเพื่อแบนด์วิดท์
และคุณต้องระมัดระวังเกี่ยวกับวิธีการแยกโค้ดด้วย การแยกโค้ดเป็นการเพิ่มประสิทธิภาพที่ยอดเยี่ยมซึ่งจะเป็นการลดจำนวน JavaScript ที่โหลดในระหว่างการเริ่มต้นใช้งาน แต่การโต้ตอบอาจล่าช้าหากใช้ JavaScript ที่โหลดโดยตรงตั้งแต่ช่วงเริ่มต้นการโต้ตอบ เพื่อชดเชยกรณีนี้ คุณจะต้องตรวจสอบเจตนาของผู้ใช้และแทรกการโหลดล่วงหน้าสำหรับ JavaScript ส่วนที่จำเป็นก่อนจะมีการโต้ตอบ ตัวอย่างเช่น การโหลด JavaScript ล่วงหน้าที่ต้องใช้เพื่อตรวจสอบความถูกต้องของเนื้อหาของฟอร์มเมื่อโฟกัสช่องใดๆ ในแบบฟอร์ม
บทสรุป
เพื่อปรับปรุงความเร็วของหน้าเว็บ ให้โหลดทรัพยากรสำคัญที่เบราว์เซอร์ค้นพบล่าช้าก่อน การโหลดทุกอย่างไว้ล่วงหน้าอาจจะไม่เกิดผลดีได้ ดังนั้นโปรดใช้ preload
น้อยๆ และวัดผลกระทบที่เกิดขึ้นในชีวิตจริง