ดึงทรัพยากรล่วงหน้าเพื่อให้การนำทางในอนาคตรวดเร็วขึ้น

ดูข้อมูลเกี่ยวกับคำแนะนำทรัพยากร rel=prefetch และวิธีการใช้งาน

เจเรมี แวกเนอร์
เจเรมี แวกเนอร์

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

คู่มือนี้อธิบายวิธีบรรลุเป้าหมายดังกล่าวด้วย <link rel=prefetch> ซึ่งเป็นคําแนะนําเกี่ยวกับทรัพยากรที่ช่วยให้คุณใช้การดึงข้อมูลล่วงหน้าได้อย่างง่ายดายและมีประสิทธิภาพ

ปรับปรุงการนำทางด้วย rel=prefetch

การเพิ่ม <link rel=prefetch> ลงในหน้าเว็บจะบอกให้เบราว์เซอร์ดาวน์โหลดทั้งหน้า หรือทรัพยากรบางอย่าง (เช่น สคริปต์หรือไฟล์ CSS) ที่ผู้ใช้อาจต้องใช้ในอนาคต

<link rel="prefetch" href="/articles/" as="document">

แผนภาพแสดงวิธีการทำงานของการดึงข้อมูลลิงก์ล่วงหน้า

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

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

Use Case

การโหลดหน้าที่ตามมาล่วงหน้า

ดึงเอกสาร HTML ล่วงหน้าเมื่อสามารถคาดการณ์หน้าต่อๆ ไปได้ เพื่อที่ว่าเมื่อคลิกลิงก์แล้ว หน้านั้นจะถูกโหลดโดยทันที

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

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

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

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

ตัวอย่างเช่น Netflix ใช้ประโยชน์จากเวลาที่ผู้ใช้อยู่ในหน้าที่ออกจากระบบเพื่อดึงข้อมูล React ล่วงหน้า ซึ่งจะใช้เมื่อผู้ใช้ลงชื่อเข้าสู่ระบบ ทำให้ประหยัดเวลาในการโต้ตอบได้ 30% สำหรับการนำทางในอนาคต

ผลกระทบของการดึงข้อมูลเนื้อหาแบบคงที่ล่วงหน้าต่อเมตริกประสิทธิภาพจะขึ้นอยู่กับทรัพยากรที่มีการดึงข้อมูลล่วงหน้า

  • การดึงข้อมูลรูปภาพล่วงหน้าอาจลดเวลา LCP ขององค์ประกอบรูปภาพ LCP ได้อย่างมาก
  • การดึงข้อมูลสไตล์ชีตล่วงหน้าจะช่วยปรับปรุงทั้ง FCP และ LCP เนื่องจากเวลาของเครือข่ายในการดาวน์โหลดสไตล์ชีตจะหมดไป เนื่องจากสไตล์ชีตมีการบล็อกการแสดงผล จึงสามารถลด LCP เมื่อดึงข้อมูลล่วงหน้า ในกรณีที่องค์ประกอบ LCP ของหน้าเว็บที่ตามมาคือภาพพื้นหลัง CSS ที่ขอผ่านพร็อพเพอร์ตี้ background-image ระบบจะดึงข้อมูลรูปภาพล่วงหน้าเป็นทรัพยากรที่เกี่ยวข้องของสไตล์ชีตที่ดึงข้อมูลล่วงหน้าด้วย
  • การดึงข้อมูล JavaScript ล่วงหน้าจะช่วยให้การประมวลผลสคริปต์ที่ดึงข้อมูลล่วงหน้าเกิดขึ้นเร็วกว่าในกรณีที่เครือข่ายต้องดึงข้อมูลก่อนในระหว่างการนำทาง การดำเนินการนี้อาจส่งผลกระทบต่อเมตริกการตอบสนอง เช่น First Input Delay (FID) และ Interaction to Next Paint (INP) ในกรณีที่มาร์กอัปแสดงของไคลเอ็นต์ผ่าน JavaScript ก็สามารถปรับปรุง LCP ด้วยความล่าช้าในการโหลดทรัพยากรที่ลดลง และการแสดงผลมาร์กอัปฝั่งไคลเอ็นต์ที่มีองค์ประกอบ LCP ของหน้าเว็บอาจเร็วขึ้น
  • การดึงข้อมูลแบบอักษรเว็บที่หน้าเว็บปัจจุบันไม่ได้ใช้อยู่ล่วงหน้าจะช่วยลดการเปลี่ยนเลย์เอาต์ได้ ในกรณีที่ใช้ font-display: swap; ระบบจะตัดระยะเวลาการสลับแบบอักษรออก ทำให้ข้อความแสดงผลเร็วขึ้นและลดการเปลี่ยนเลย์เอาต์ หากหน้าเว็บในอนาคตใช้แบบอักษรที่ดึงข้อมูลล่วงหน้าและองค์ประกอบ LCP ของหน้าเว็บเป็นบล็อกข้อความที่ใช้แบบอักษรเว็บ LCP ขององค์ประกอบดังกล่าวจะทำงานเร็วขึ้นเช่นกัน

การดึงข้อมูลส่วน JavaScript แบบออนดีมานด์ล่วงหน้า

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

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

วิธีใช้ rel=prefetch

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

<head>
  ...
  <link rel="prefetch" href="/articles/" as="document">
  ...
</head>

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

นอกจากนี้ คุณยังเริ่มการดึงข้อมูลล่วงหน้าผ่านส่วนหัว HTTP Link ได้ด้วย โดยทำดังนี้

Link: </css/style.css>; rel=prefetch

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

การโหลดโมดูล JavaScript ล่วงหน้าที่มีความคิดเห็นวิเศษของ Webpack

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

ข้อมูลโค้ดต่อไปนี้จะโหลดฟังก์ชันการจัดเรียงจากไลบรารี lodash เพื่อจัดเรียงกลุ่มตัวเลขที่จะส่งตามแบบฟอร์ม

form.addEventListener("submit", e => {
  e.preventDefault()
  import('lodash.sortby')
    .then(module => module.default)
    .then(sortInput())
    .catch(err => { alert(err) });
});

แทนที่จะรอให้กิจกรรม "ส่ง" เกิดขึ้นเพื่อโหลดฟังก์ชันนี้ คุณสามารถดึงข้อมูลทรัพยากรนี้ล่วงหน้าเพื่อเพิ่มโอกาสที่จะทำให้ทรัพยากรอยู่ในแคชได้ตามเวลาที่ผู้ใช้ส่งแบบฟอร์ม Webpack อนุญาตให้ใช้ความคิดเห็นพิเศษใน import() ได้ ดังนี้

form.addEventListener("submit", e => {
   e.preventDefault()
   import(/* webpackPrefetch: true */ 'lodash.sortby')
         .then(module => module.default)
         .then(sortInput())
         .catch(err => { alert(err) });
});

การดำเนินการนี้จะบอกให้ Webpack แทรกแท็ก <link rel="prefetch"> ลงในเอกสาร HTML

<link rel="prefetch" as="script" href="1.bundle.js">

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

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

นอกจากนี้ คุณยังใช้การดึงข้อมูลล่วงหน้าที่ชาญฉลาดได้ด้วยไลบรารีที่ใช้ prefetch ขั้นสูง

ทั้ง quicklink และ Guess.js จะใช้ Network Information API เพื่อหลีกเลี่ยงการดึงข้อมูลล่วงหน้าหากผู้ใช้อยู่ในเครือข่ายที่ช้าหรือเปิด Save-Data ไว้

การดึงข้อมูลล่วงหน้าขั้นสูง

คำแนะนำเกี่ยวกับแหล่งข้อมูลไม่ใช่คำสั่งที่บังคับและขึ้นอยู่กับเบราว์เซอร์ว่าจะเรียกใช้งานหรือไม่และเมื่อใด

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

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

ไฟล์ที่ดึงข้อมูลล่วงหน้าจะจัดเก็บอยู่ในแคช HTTP หรือแคชหน่วยความจำ (ขึ้นอยู่กับว่าแหล่งข้อมูลนั้นสามารถแคชได้หรือไม่) ตามระยะเวลาที่แตกต่างกันไปตามเบราว์เซอร์ ตัวอย่างเช่น ในทรัพยากรของ Chrome จะเก็บไว้ประมาณ 5 นาที หลังจากนั้นกฎ Cache-Control ปกติสำหรับทรัพยากรก็จะมีผล

บทสรุป

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