การเสริมเทคนิคการดึงข้อมูลล่วงหน้าแบบดั้งเดิมด้วย Service Worker
การดำเนินการในเว็บไซต์มักมีหลายขั้นตอน ตัวอย่างเช่น การซื้อผลิตภัณฑ์ในเว็บไซต์อีคอมเมิร์ซอาจเกี่ยวข้องกับการค้นหาผลิตภัณฑ์ การเลือกสินค้าจากรายการผลการค้นหา เพิ่มสินค้าลงในรถเข็น และดำเนินการให้เสร็จสมบูรณ์ด้วยการชำระเงิน
ในทางเทคนิคแล้ว การย้ายผ่านหน้าต่างๆ หมายถึงการสร้างคำขอการนำทาง ตามกฎทั่วไป คุณไม่ต้องการใช้ส่วนหัว Cache-Control
ที่ใช้ได้นานเพื่อแคชการตอบกลับ HTML สำหรับคำขอการนำทาง โดยปกติแล้วผู้ใช้ควรพอใจผ่านเครือข่ายด้วย Cache-Control: no-cache
เพื่อให้มั่นใจว่า HTML รวมถึงเชนของคำขอเครือข่ายที่ตามมามีความใหม่ (อย่างสมเหตุสมผล)
การที่ต้องเชื่อมต่อกับเครือข่ายทุกครั้งที่ผู้ใช้ไปยังหน้าใหม่หมายความว่าการนำทางแต่ละครั้งอาจทำได้ช้า และอย่างน้อยที่สุดก็หมายความว่าการนำทางนั้นจะไม่เร็วที่เชื่อถือได้
เพื่อให้คำขอเหล่านี้รวดเร็วขึ้น หากคุณสามารถคาดการณ์การดำเนินการของผู้ใช้ได้ คุณสามารถขอหน้าเว็บและองค์ประกอบเหล่านี้ล่วงหน้า และเก็บไว้ในแคชเป็นระยะเวลาสั้นๆ จนกว่าผู้ใช้จะคลิกลิงก์เหล่านี้ เทคนิคนี้เรียกว่าprefetching และโดยทั่วไปมักจะนำมาใช้โดยการเพิ่มแท็ก <link rel="prefetch">
ลงในหน้าเว็บต่างๆ เพื่อบ่งบอกถึงทรัพยากรที่จะดึงข้อมูลล่วงหน้า
ในคู่มือนี้เราจะสำรวจวิธีต่างๆ ที่คุณจะใช้โปรแกรมทำงานของบริการร่วมกับเทคนิคการดึงข้อมูลล่วงหน้าแบบดั้งเดิมได้
เคสการผลิต
MercadoLibre เป็นเว็บไซต์อีคอมเมิร์ซที่ใหญ่ที่สุดในลาตินอเมริกา บริษัทจะแทรกแท็ก <link rel="prefetch">
แบบไดนามิกในบางส่วนของขั้นตอน เพื่อเพิ่มความเร็วในการไปยังส่วนต่างๆ ตัวอย่างเช่น ในหน้ารายชื่อ ผู้ใช้จะดึงข้อมูลหน้าผลลัพธ์ถัดไปทันทีที่ผู้ใช้เลื่อนลงไปที่ด้านล่างของรายชื่อ
ระบบขอไฟล์ที่ดึงข้อมูลล่วงหน้าได้ที่ระดับ "ต่ำสุด" และจัดเก็บไว้ในแคช HTTP หรือแคชหน่วยความจำ (ขึ้นอยู่กับว่าทรัพยากรดังกล่าวสามารถแคชได้หรือไม่) โดยเป็นระยะเวลาที่แตกต่างกันไปตามเบราว์เซอร์ ตัวอย่างเช่น สำหรับ Chrome 85 ค่านี้คือ 5 นาที ระบบจะเก็บทรัพยากรไว้ประมาณ 5 นาที หลังจากนั้นกฎ Cache-Control
ปกติสำหรับทรัพยากรจะมีผลบังคับใช้
การใช้การแคชของ Service Worker จะช่วยยืดอายุการใช้งานของการดึงข้อมูลทรัพยากรล่วงหน้าไปมากกว่ากรอบเวลา 5 นาที
ตัวอย่างเช่น Virgilio Sport ซึ่งเป็นพอร์ทัลกีฬาของอิตาลีจะใช้โปรแกรมทำงานของบริการเพื่อดึงข้อมูลโพสต์ที่ได้รับความนิยมสูงสุดในหน้าแรกล่วงหน้า นอกจากนี้ ยังใช้ Network Information API เพื่อหลีกเลี่ยงการดึงข้อมูลล่วงหน้าสำหรับผู้ใช้ที่ใช้การเชื่อมต่อ 2G ด้วย
ผลที่ตามมาคือจากการสังเกตการณ์ Virgilio Sport เห็นเวลาในการโหลดสำหรับการนำทางไปยังบทความเพิ่มขึ้น 78% และจำนวนการแสดงผลบทความเพิ่มขึ้น 45%
ใช้การแคชล่วงหน้าด้วย Workbox
ในส่วนต่อไปนี้ เราจะใช้กล่องทำงานเพื่อแสดงวิธีการใช้เทคนิคการแคชต่างๆ ใน Service Worker ที่สามารถใช้เป็นส่วนเสริมของ <link rel="prefetch">
หรือแม้แต่ใช้ทดแทนโดยการมอบสิทธิ์งานนี้ให้กับ Service Worker โดยสมบูรณ์
1. หน้าเว็บแบบคงที่และทรัพยากรย่อยของหน้าเพื่อแคชล่วงหน้า
การแคชล่วงหน้าเป็นความสามารถของโปรแกรมทำงานของบริการเพื่อบันทึกไฟล์ไปยังแคชขณะติดตั้ง
กรณีต่อไปนี้คือการใช้การแคชล่วงหน้าเพื่อให้บรรลุเป้าหมายที่คล้ายกับการดึงข้อมูลล่วงหน้า นั่นคือการทำให้การนำทางรวดเร็วขึ้น
การแคชหน้าเว็บแบบคงที่ล่วงหน้า
สำหรับหน้าเว็บที่สร้างขึ้น ณ เวลาสร้าง (เช่น about.html
, contact.html
) หรือในเว็บไซต์ที่คงที่โดยสมบูรณ์ หนึ่งเอกสารสามารถเพิ่มเอกสารของเว็บไซต์ไปยังรายการแคชล่วงหน้า เอกสารเหล่านี้จะพร้อมใช้งานในแคชทุกครั้งที่ผู้ใช้เข้าถึงเอกสาร:
workbox.precaching.precacheAndRoute([
{url: '/about.html', revision: 'abcd1234'},
// ... other entries ...
]);
ทรัพยากรย่อยของหน้าการแคชล่วงหน้า
การแคชเนื้อหาแบบคงที่ล่วงหน้าซึ่งส่วนต่างๆ ของเว็บไซต์อาจใช้ (เช่น JavaScript, CSS ฯลฯ) เป็นแนวทางปฏิบัติแนะนำทั่วไปและจะช่วยเพิ่มสถานการณ์การดึงข้อมูลล่วงหน้าให้มากขึ้น
หากต้องการเพิ่มความเร็วในการไปยังส่วนต่างๆ ในเว็บไซต์อีคอมเมิร์ซ ให้ใช้แท็ก <link rel="prefetch">
ในหน้าข้อมูลเพื่อดึงข้อมูลหน้ารายละเอียดผลิตภัณฑ์ล่วงหน้าสำหรับผลิตภัณฑ์ 2-3 รายการแรกของหน้าข้อมูล หากคุณแคชทรัพยากรย่อยของหน้าผลิตภัณฑ์ไว้ล่วงหน้าแล้ว ก็จะช่วยให้ไปยังส่วนต่างๆ ได้เร็วขึ้น
หากต้องการดำเนินการดังกล่าว ให้ทำดังนี้
- เพิ่มแท็ก
<link rel="prefetch">
ลงในหน้า
<link rel="prefetch" href="/phones/smartphone-5x.html" as="document">
- เพิ่มทรัพยากรย่อยของหน้าลงในรายการแคชล่วงหน้าใน Service Worker ดังนี้
workbox.precaching.precacheAndRoute([
'/styles/product-page.ac29.css',
// ... other entries ...
]);
2. ยืดอายุการใช้งานของทรัพยากรสำหรับการดึงข้อมูลล่วงหน้า
ดังที่กล่าวไว้ก่อนหน้านี้ <link rel="prefetch">
จะดึงข้อมูลและเก็บทรัพยากรในแคช HTTP เป็นระยะเวลาหนึ่ง หลังจากนั้นจะมีการใช้กฎ Cache-Control
สำหรับทรัพยากร ค่านี้คือ 5 นาทีสำหรับ Chrome 85
Service Worker ช่วยให้คุณยืดอายุการใช้งานของหน้าเว็บที่ดึงข้อมูลล่วงหน้าได้ ขณะเดียวกันก็ให้ประโยชน์เพิ่มเติมในการทำให้ทรัพยากรเหล่านี้พร้อมใช้งานแบบออฟไลน์ด้วย
ในตัวอย่างก่อนหน้านี้ ตัวแปรสามารถเสริม <link rel="prefetch">
ที่ใช้ในการดึงข้อมูลหน้าผลิตภัณฑ์ล่วงหน้าด้วยกลยุทธ์การแคชรันไทม์ของ Workbox
ในการใช้งาน ให้ทำดังนี้
- เพิ่มแท็ก
<link rel="prefetch">
ลงในหน้า
<link rel="prefetch" href="/phones/smartphone-5x.html" as="document">
- ใช้กลยุทธ์การแคชรันไทม์ใน Service Worker สำหรับคำขอประเภทต่อไปนี้
new workbox.strategies.StaleWhileRevalidate({
cacheName: 'document-cache',
plugins: [
new workbox.expiration.Plugin({
maxAgeSeconds: 30 * 24 * 60 * 60, // 30 Days
}),
],
});
ในกรณีนี้ เราเลือกใช้กลยุทธ์ที่ไม่มีการอัปเดตขณะตรวจสอบความถูกต้องอีกครั้ง ในกลยุทธ์นี้ หน้าเว็บสามารถขอได้จากทั้งแคชและเครือข่ายพร้อมกัน การตอบกลับจะมาจากแคช (หากมี) หรือมาจากเครือข่าย แคชจะอัปเดตอยู่เสมอเมื่อมีคำขอที่สำเร็จแต่ละรายการ
3. มอบสิทธิ์การดึงข้อมูลล่วงหน้าให้กับ Service Worker
ในกรณีส่วนใหญ่ วิธีที่ดีที่สุดคือการใช้ <link rel="prefetch">
แท็กนี้เป็นคำแนะนำด้านทรัพยากรที่ออกแบบมาเพื่อทำให้การดึงข้อมูลล่วงหน้ามีประสิทธิภาพมากที่สุดเท่าที่จะเป็นไปได้
แต่ในบางกรณี การมอบสิทธิ์ทำงานนี้ทั้งหมดให้กับโปรแกรมทำงานของบริการอาจเป็นประโยชน์มากกว่า
เช่น หากต้องการดึงข้อมูลผลิตภัณฑ์ 2-3 รายการแรกล่วงหน้าในหน้าข้อมูลผลิตภัณฑ์ที่แสดงฝั่งไคลเอ็นต์ ลูกค้าอาจต้องแทรกแท็ก <link rel="prefetch">
หลายรายการแบบไดนามิกในหน้าเว็บตามการตอบกลับของ API ซึ่งอาจใช้เวลานานในเทรดหลักของหน้าและทําให้ติดตั้งใช้งานได้ยากขึ้น
ในกรณีเช่นนี้ ให้ใช้ "กลยุทธ์การสื่อสารของโปรแกรมทำงานของบริการ (Page to Service Worker)" เพื่อมอบหมายงานสำหรับการดึงข้อมูลล่วงหน้าให้แก่ Service Worker โดยสมบูรณ์ คุณสื่อสารประเภทนี้ได้โดยใช้ worker.postMessage():
แพ็กเกจหน้าต่าง Workbox จะช่วยลดความซับซ้อนของการสื่อสารประเภทนี้ โดยลดรายละเอียดต่างๆ ของการเรียกที่ดำเนินอยู่
การดึงข้อมูลล่วงหน้าด้วยหน้าต่างกล่องงานสามารถใช้วิธีดังต่อไปนี้
- ในหน้าเว็บ ให้เรียกใช้ Service Worker ผ่านประเภทของข้อความและรายการ URL ที่จะดึงข้อมูลล่วงหน้า ดังนี้
const wb = new Workbox('/sw.js');
wb.register();
const prefetchResponse = await wb.messageSW({type: 'PREFETCH_URLS', urls: […]});
- ในโปรแกรมทำงานของบริการ: ใช้เครื่องจัดการข้อความเพื่อส่งคำขอ
fetch()
สำหรับ URL แต่ละรายการเพื่อดึงข้อมูลล่วงหน้า
addEventListener('message', (event) => {
if (event.data.type === 'PREFETCH_URLS') {
// Fetch URLs and store them in the cache
}
});