tl;dr
ตั้งแต่ Chrome 68 เป็นต้นไป คำขอ HTTP ที่ตรวจหาอัปเดตสคริปต์ Service Worker จะไม่ถูกดำเนินการด้วยแคช HTTP อีกต่อไปโดยค่าเริ่มต้น วิธีนี้ช่วยแก้ปัญหาปัญหาทั่วไปของนักพัฒนาซอฟต์แวร์ ซึ่งการตั้งค่าส่วนหัว Cache-Control
โดยไม่ตั้งใจในสคริปต์โปรแกรมทำงานของบริการอาจทำให้การอัปเดตล่าช้า
หากคุณเลือกไม่ใช้การแคช HTTP สำหรับสคริปต์ /service-worker.js
โดยแสดงสคริปต์ด้วย Cache-Control: max-age=0
แล้ว คุณไม่น่าจะเห็นการเปลี่ยนแปลงเนื่องจากลักษณะการทำงานเริ่มต้นแบบใหม่
นอกจากนี้ ตั้งแต่ Chrome 78 เป็นต้นไป ระบบจะใช้การเปรียบเทียบแบบไบต์ต่อไบต์กับสคริปต์ที่โหลดใน Service Worker ผ่าน importScripts()
การเปลี่ยนแปลงสคริปต์ที่นำเข้าจะทริกเกอร์ขั้นตอนการอัปเดตโปรแกรมทำงานของบริการ เช่นเดียวกับการเปลี่ยนแปลงโปรแกรมทำงานของบริการระดับบนสุด
ที่มา
ทุกครั้งที่คุณไปยังหน้าใหม่ที่อยู่ในขอบเขตของ Service Worker ให้เรียกใช้ registration.update()
จาก JavaScript อย่างชัดแจ้ง หรือเมื่อ Service Worker "ตื่น" ผ่านเหตุการณ์ push
หรือ sync
เบราว์เซอร์จะขอทรัพยากร JavaScript ที่ส่งไปยังการเรียก navigator.serviceWorker.register()
ก่อนหน้านี้เพื่อค้นหาอัปเดตสคริปต์โปรแกรมทำงานของบริการไปด้วย
สำหรับบทความนี้ สมมติว่า URL ของบทความคือ /service-worker.js
และมีการเรียก importScripts()
ครั้งเดียว ซึ่งจะโหลดโค้ดเพิ่มเติมที่ทำงานภายใน Service Worker
// Inside our /service-worker.js file:
importScripts('path/to/import.js');
// Other top-level code goes here.
สิ่งที่เปลี่ยนแปลงไป
ก่อน Chrome 68 คำขออัปเดตสำหรับ /service-worker.js
จะดำเนินการผ่านแคช HTTP
(เนื่องจากมีการดึงข้อมูลส่วนใหญ่) ซึ่งหมายความว่าหากส่งสคริปต์ด้วย Cache-Control:
max-age=600
ในตอนแรก การอัปเดตภายใน 600 วินาที (10 นาที) จะไม่ไปยังเครือข่าย ดังนั้นผู้ใช้อาจไม่ได้รับ Service Worker เวอร์ชันล่าสุด แต่หาก max-age
มากกว่า 86400 (24 ชั่วโมง) ระบบจะปฏิบัติเสมือนเป็น 86400 เพื่อป้องกันไม่ให้ผู้ใช้ติดอยู่กับเวอร์ชันใดเวอร์ชันหนึ่งตลอดไป
ตั้งแต่ปี 68 เป็นต้นไป ระบบจะไม่สนใจแคช HTTP เมื่อขออัปเดตสคริปต์ Service Worker ดังนั้นเว็บแอปพลิเคชันที่มีอยู่จึงอาจเห็นความถี่ของคำขอสำหรับสคริปต์ Service Worker เพิ่มขึ้น คำขอสำหรับ importScripts
จะยังคงส่งผ่านแคช HTTP แต่นี่เป็นเพียงตัวเลือกเริ่มต้น ซึ่งก็คือตัวเลือกการจดทะเบียนใหม่ updateViaCache
ที่พร้อมใช้งานซึ่งให้คุณควบคุมลักษณะการทำงานนี้ได้
updateViaCache
ตอนนี้นักพัฒนาซอฟต์แวร์จะส่งตัวเลือกใหม่เมื่อเรียกใช้ navigator.serviceWorker.register()
ได้ นั่นคือพารามิเตอร์ updateViaCache
โดยจะใช้ 1 ใน 3 ค่า ได้แก่ 'imports'
, 'all'
หรือ 'none'
ค่าดังกล่าวจะกำหนดว่าแคช HTTP มาตรฐานของเบราว์เซอร์จะเข้ามามีบทบาทหรือไม่และจะมีผลอย่างไรเมื่อส่งคำขอ HTTP เพื่อตรวจสอบทรัพยากรของ Service Worker ที่อัปเดต
เมื่อตั้งค่าเป็น
'imports'
ระบบจะไม่ปรึกษาแคช HTTP เมื่อตรวจหาการอัปเดตสคริปต์/service-worker.js
แต่ระบบจะปรึกษาเมื่อดึงข้อมูลสคริปต์ที่นำเข้า (เช่นpath/to/import.js
) ซึ่งเป็นค่าเริ่มต้นและตรงกับลักษณะการทํางานเริ่มต้นใน Chrome 68เมื่อตั้งค่าเป็น
'all'
ระบบจะพิจารณาแคช HTTP เมื่อส่งคำขอสำหรับสคริปต์/service-worker.js
ระดับบนสุด รวมถึงสคริปต์ที่นำเข้าภายในโปรแกรมทำงานของบริการ เช่นpath/to/import.js
ตัวเลือกนี้สอดคล้องกับลักษณะการทำงานก่อนหน้าใน Chrome ก่อนหน้า Chrome 68เมื่อตั้งค่าเป็น
'none'
ระบบจะไม่พิจารณาแคช HTTP เมื่อส่งคำขอสำหรับ/service-worker.js
ระดับบนสุดหรือสคริปต์ที่นำเข้า เช่นpath/to/import.js
สมมติ
เช่น โค้ดต่อไปนี้จะลงทะเบียน Service Worker และตรวจสอบว่าไม่มีการปรึกษาแคช HTTP เมื่อตรวจหาการอัปเดตสคริปต์ /service-worker.js
หรือสำหรับสคริปต์ที่อ้างอิงผ่าน importScripts()
ภายใน /service-worker.js
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/service-worker.js', {
updateViaCache: 'none',
// Optionally, set 'scope' here, if needed.
});
}
ตรวจหาการอัปเดตสคริปต์ที่นำเข้า
ก่อน Chrome 78 ระบบจะเรียกสคริปต์ของ Service Worker ที่โหลดผ่าน importScripts()
เพียงครั้งเดียว (ตรวจสอบกับแคช HTTP ก่อน หรือผ่านเครือข่าย โดยขึ้นอยู่กับการกำหนดค่า updateViaCache
) หลังจากการดึงข้อมูลครั้งแรก เบราว์เซอร์จะจัดเก็บไว้ในภายในและไม่เรียกข้อมูลอีก
วิธีเดียวที่จะบังคับให้โปรแกรมทำงานของบริการที่ติดตั้งไว้แล้วยอมรับการเปลี่ยนแปลงของสคริปต์ที่นำเข้าคือการเปลี่ยน URL ของสคริปต์ ซึ่งโดยปกติจะเป็นการเพิ่มค่าเซมเวอร์ (เช่น importScripts('https://example.com/v1.1.0/index.js')
) หรือใส่แฮชของเนื้อหา (เช่น importScripts('https://example.com/index.abcd1234.js')
) ผลข้างเคียงจากการเปลี่ยน URL ที่นำเข้าคือการเปลี่ยนแปลงเนื้อหาของสคริปต์บริการระดับบนสุด ซึ่งจะทำให้ขั้นตอนการอัปเดตในโปรแกรมทำงานของบริการระดับบนสุดจะทริกเกอร์ขั้นตอนการอัปเดต
ตั้งแต่ Chrome 78 เป็นต้นไป ทุกครั้งที่มีการตรวจสอบการอัปเดตสำหรับไฟล์โปรแกรมทำงานของบริการระดับบนสุด ระบบจะตรวจสอบในเวลาเดียวกันเพื่อพิจารณาว่าเนื้อหาของสคริปต์ที่นำเข้ามีการเปลี่ยนแปลงหรือไม่ แคช HTTP อาจดำเนินการตามส่วนหัว Cache-Control
ที่ใช้ หากตั้งค่า updateViaCache
เป็น 'all'
หรือ 'imports'
(ซึ่งเป็นค่าเริ่มต้น) หรือการตรวจสอบอาจดำเนินการกับเครือข่ายโดยตรงหากตั้งค่า updateViaCache
เป็น 'none'
ทั้งนี้ขึ้นอยู่กับส่วนหัว Cache-Control
ที่ใช้
หากการตรวจสอบการอัปเดตของสคริปต์ที่นำเข้าทำให้เกิดความแตกต่างแบบไบต์ต่อไบต์เมื่อเทียบกับข้อมูลที่โปรแกรมทำงานของบริการจัดเก็บไว้ก่อนหน้านี้ ระบบจะทริกเกอร์ขั้นตอนการอัปเดตโปรแกรมทำงานของบริการเต็มรูปแบบแม้ว่าไฟล์ของผู้ปฏิบัติงานบริการระดับบนสุดจะยังคงเหมือนเดิมก็ตาม
ลักษณะการทำงานของ Chrome 78 ตรงกับสิ่งที่ Firefox นำมาใช้ เมื่อหลายปีก่อนใน Firefox 56 ซึ่ง Safari ก็นำลักษณะการทำงานนี้ ไปใช้อยู่แล้วเช่นกัน
นักพัฒนาแอปต้องทำอะไรบ้าง
หากคุณเลือกไม่ใช้การแคช HTTP สำหรับสคริปต์ /service-worker.js
อย่างมีประสิทธิภาพโดยแสดงสคริปต์ด้วย Cache-Control: max-age=0
(หรือค่าที่คล้ายกัน) คุณก็ไม่ควรจะเห็นการเปลี่ยนแปลงใดๆ เนื่องจากลักษณะการทำงานเริ่มต้นใหม่
หากคุณแสดงสคริปต์ /service-worker.js
โดยเปิดใช้การแคช HTTP ไม่ว่าจะตั้งใจหรือเพราะเป็นเพียงค่าเริ่มต้นสำหรับสภาพแวดล้อมโฮสติ้ง คุณอาจเริ่มเห็นคำขอ HTTP เพิ่มเติมสำหรับ /service-worker.js
ที่สร้างขึ้นไปยังเซิร์ฟเวอร์ของคุณมีจำนวนเพิ่มขึ้น คำขอเหล่านี้คือคำขอที่ใช้แคช HTTP ดำเนินการ หากต้องการอนุญาตให้ค่าส่วนหัว Cache-Control
ส่งผลต่อความใหม่ของ /service-worker.js
ต่อไป คุณจะต้องเริ่มการตั้งค่า updateViaCache: 'all'
อย่างชัดเจนเมื่อลงทะเบียน Service Worker
เนื่องจากเบราว์เซอร์เวอร์ชันเก่าอาจมีกลุ่มผู้ใช้จำนวนมาก คุณจึงควรตั้งค่าส่วนหัว HTTP ของ Cache-Control: max-age=0
ในสคริปต์โปรแกรมทำงานของบริการต่อไป แม้ว่าเบราว์เซอร์รุ่นใหม่ๆ อาจไม่สนใจก็ตาม
นักพัฒนาซอฟต์แวร์สามารถใช้โอกาสนี้ตัดสินใจว่าต้องการเลือกไม่ใช้การแคช HTTP สำหรับสคริปต์ที่นำเข้าอย่างชัดแจ้งในตอนนี้หรือไม่ และเพิ่ม updateViaCache: 'none'
ลงในการลงทะเบียน Service Worker ของตนตามความเหมาะสม
การแสดงสคริปต์ที่นำเข้า
ตั้งแต่ Chrome 78 เป็นต้นไป นักพัฒนาซอฟต์แวร์อาจเห็นคำขอ HTTP ขาเข้าสำหรับทรัพยากรที่โหลดผ่าน importScripts()
มากขึ้น เนื่องจากตอนนี้จะมีการตรวจหาอัปเดต
หากต้องการหลีกเลี่ยงการเข้าชมผ่าน HTTP เพิ่มเติมนี้ ให้ตั้งค่าส่วนหัว Cache-Control
ที่มีอายุการใช้งานยาวนานเมื่อแสดงสคริปต์ที่มีเซมเวอร์หรือแฮชใน URL และอาศัยลักษณะการทํางาน updateViaCache
เริ่มต้นของ 'imports'
หรือหากต้องการต้องการตรวจสอบสคริปต์ที่นำเข้าเพื่อรับการอัปเดตเป็นประจำ ให้ตรวจสอบว่าแสดงสคริปต์ด้วย Cache-Control: max-age=0
หรือคุณใช้ updateViaCache: 'none'
อ่านเพิ่มเติม
"วงจรการทำงานของ Service Worker" และ "แนวทางปฏิบัติแนะนำในการแคชและ Getchas อายุสูงสุด" ซึ่งทั้ง 2 อย่างโดย Jake Archibald แนะนำให้อ่านสำหรับนักพัฒนาซอฟต์แวร์ทุกคนที่ติดตั้งใช้งานทุกอย่างบนเว็บ