ตรวจสอบว่า Service Worker ของคุณทราบสิ่งที่ต้องทําเมื่อมีการขอการตอบกลับบางส่วน
คำขอ HTTP บางรายการมีส่วนหัว Range:
ซึ่งบ่งบอกว่าควรแสดงเฉพาะบางส่วนของทรัพยากรทั้งหมด ซึ่งใช้สำหรับการสตรีมเนื้อหาเสียงหรือวิดีโอเพื่อให้โหลดสื่อกลุ่มเล็กๆ ได้แบบออนดีมานด์ แทนที่จะขอไฟล์ระยะไกลทั้งหมดในคราวเดียว
โปรแกรมทำงานของบริการ คือโค้ด JavaScript ที่อยู่ระหว่างเว็บแอปกับเครือข่าย ซึ่งอาจสกัดกั้นคำขอของเครือข่ายขาออกและสร้างการตอบกลับให้กับคำขอเหล่านั้นได้
ที่ผ่านมา คำขอช่วงและ Service Worker ทำงานร่วมกันไม่ค่อยดี คุณจึงต้องทำตามขั้นตอนพิเศษเพื่อหลีกเลี่ยงผลลัพธ์ที่ไม่พึงประสงค์ใน Service Worker แต่โชคดีที่สถานการณ์นี้เริ่มเปลี่ยนแปลงไป ในเบราว์เซอร์ที่แสดงลักษณะการทำงานที่ถูกต้อง คำขอช่วงจะ "ทํางานได้" เมื่อส่งผ่าน Service Worker
ปัญหาคืออะไร
พิจารณา Service Worker ที่มี Listener เหตุการณ์ fetch
ต่อไปนี้ ซึ่งจะรับคำขอที่เข้ามาทั้งหมดและส่งไปยังเครือข่าย:
self.addEventListener('fetch', (event) => {
// The Range: header will not pass through in
// browsers that behave incorrectly.
event.respondWith(fetch(event.request));
});
ในเบราว์เซอร์ที่มีลักษณะการทำงานที่ไม่ถูกต้อง หาก event.request
มีส่วนหัว Range:
ส่วนหัวนั้นจะหายไปโดยไม่มีการแจ้งเตือน คำขอที่ได้รับจากเซิร์ฟเวอร์ระยะไกลจะไม่มี Range:
เลย การดำเนินการนี้ไม่จําเป็นต้อง "ขัดข้อง" แต่อย่างใด เนื่องจากในทางเทคนิคแล้ว เซิร์ฟเวอร์ได้รับอนุญาตให้แสดงผลเนื้อหาการตอบกลับแบบเต็มพร้อมรหัสสถานะ 200
แม้ว่าจะมีส่วนหัว Range:
ในคําขอต้นฉบับก็ตาม แต่วิธีนี้จะทำให้มีการโอนข้อมูลมากกว่าที่จำเป็นจากมุมมองของเบราว์เซอร์
นักพัฒนาแอปที่ทราบถึงลักษณะการทำงานนี้สามารถแก้ปัญหาได้โดยการตรวจสอบว่ามีส่วนหัว Range:
อยู่หรือไม่อย่างชัดเจน และจะไม่เรียกใช้ event.respondWith()
หากมี ซึ่งการดําเนินการนี้จะช่วยให้ Service Worker ตัดตัวเองออกจากภาพรวมการสร้างการตอบกลับได้อย่างมีประสิทธิภาพ และระบบจะใช้ตรรกะการทํางานของเครือข่ายเบราว์เซอร์เริ่มต้นซึ่งทราบวิธีเก็บรักษาคําขอช่วงแทน
self.addEventListener('fetch', (event) => {
// Return without calling event.respondWith()
// if this is a range request.
if (event.request.headers.has('range')) {
return;
}
event.respondWith(fetch(event.request));
});
เราพูดได้ว่านักพัฒนาแอปส่วนใหญ่ไม่ทราบถึงความจำเป็นในการดำเนินการนี้ และไม่ได้ระบุเหตุผลว่าจะต้องกำหนดไว้อย่างชัดเจน ในที่สุด ข้อจํากัดนี้เกิดขึ้นเนื่องจากเบราว์เซอร์ต้องตามทันการเปลี่ยนแปลงในข้อกําหนดพื้นฐาน ซึ่งเพิ่มการรองรับฟังก์ชันการทํางานนี้
มีการแก้ไขอะไรบ้าง
เบราว์เซอร์ที่ทํางานอย่างถูกต้องจะเก็บรักษาส่วนหัว Range:
ไว้เมื่อมีการส่ง event.request
ไปยัง fetch()
ซึ่งหมายความว่าโค้ด Service Worker ในตัวอย่างแรกจะอนุญาตให้เซิร์ฟเวอร์ระยะไกลเห็นส่วนหัว Range:
หากเบราว์เซอร์เป็นผู้ตั้งค่า
self.addEventListener('fetch', (event) => {
// The Range: header will pass through in browsers
// that behave correctly.
event.respondWith(fetch(event.request));
});
ตอนนี้เซิร์ฟเวอร์มีโอกาสจัดการคำขอช่วงอย่างถูกต้องและแสดงการตอบกลับบางส่วนด้วยรหัสสถานะ 206
เบราว์เซอร์ใดทำงานอย่างถูกต้อง
Safari เวอร์ชันล่าสุดมีฟังก์ชันการทำงานที่ถูกต้อง Chrome และ Edge ตั้งแต่เวอร์ชัน 87 ทำงานได้อย่างถูกต้องเช่นกัน
ตั้งแต่เดือนตุลาคม 2020 นี้ Firefox ยังไม่ได้แก้ไขการทำงานดังกล่าว คุณจึงอาจต้องคำนึงถึงปัญหานี้ในระหว่างที่ทำให้โค้ดของโปรแกรมทำงานของบริการใช้งานได้จริง
การตรวจสอบแถว "รวมส่วนหัวช่วงในคำขอเครือข่าย" ของหน้าแดชบอร์ดการทดสอบแพลตฟอร์มเว็บเป็นวิธีที่ดีที่สุดในการยืนยันว่าเบราว์เซอร์หนึ่งๆ แก้ไขลักษณะการทำงานนี้หรือไม่
การแสดงคําขอช่วงจากแคชจะเป็นอย่างไร
เซอร์วิสเวิร์กทําได้มากกว่าแค่ส่งคําขอไปยังเครือข่าย กรณีการใช้งานที่พบบ่อยคือการเพิ่มทรัพยากร เช่น ไฟล์เสียงและวิดีโอ ลงในแคชในเครื่อง จากนั้น Service Worker จะดำเนินการตามคำขอจากแคชดังกล่าวได้โดยไม่ต้องใช้เครือข่ายเลย
เบราว์เซอร์ทั้งหมด รวมถึง Firefox รองรับการตรวจสอบคำขอภายในเครื่องจัดการ fetch
, ตรวจสอบว่ามีส่วนหัว Range:
หรือไม่ จากนั้นดำเนินการตามคำขอด้วยการตอบกลับ 206
ที่มาจากแคช อย่างไรก็ตาม โค้ด Service Worker สำหรับการแยกวิเคราะห์ส่วนหัว Range:
อย่างถูกต้องและแสดงเฉพาะส่วนที่สอดคล้องกันของการตอบกลับที่แคชไว้อย่างสมบูรณ์นั้นไม่ใช่เรื่องง่าย
แต่นักพัฒนาซอฟต์แวร์ที่ต้องการความช่วยเหลือสามารถหันมาใช้ Workbox ซึ่งเป็นชุดไลบรารีที่ลดความซับซ้อนของกรณีการใช้งาน Service Worker ทั่วไป workbox-range-request module
ใช้ตรรกะทั้งหมดที่จําเป็นในการแสดงคําตอบบางส่วนจากแคชโดยตรง ดูสูตรการใช้งานทั้งหมดสำหรับกรณีการใช้งานนี้ได้ในเอกสารประกอบของ Workbox
รูปภาพหลักในโพสต์นี้เป็นผลงานของ Natalie Rhea Riggs ใน Unsplash