โปรแกรมทำงานของบริการที่ใหม่กว่าโดยค่าเริ่มต้น

DR

ตั้งแต่ Chrome 68 เป็นต้นไป คำขอ HTTP ที่ตรวจหาการอัปเดตสคริปต์ Service Worker จะไม่ส่ง จะมีการประมวลผลด้วยแคช HTTP นานขึ้น โดยค่าเริ่มต้น วิธีแก้ปัญหานี้เกี่ยวกับปัญหาทั่วไปของนักพัฒนาซอฟต์แวร์ ซึ่งทำให้การตั้งค่าส่วนหัว Cache-Control โดยไม่ตั้งใจในสคริปต์โปรแกรมทำงานของบริการอาจทำให้เกิด ในการอัปเดตที่ล่าช้า

หากคุณเลือกไม่ใช้การแคช HTTP สำหรับสคริปต์ /service-worker.js โดยแสดงสคริปต์แล้ว เมื่อใช้ Cache-Control: max-age=0 คุณจะไม่เห็นการเปลี่ยนแปลงเนื่องจากค่าเริ่มต้นใหม่ พฤติกรรมของคุณ

นอกจากนี้ เริ่มตั้งแต่ Chrome 78 เป็นต้นไป การเปรียบเทียบแบบไบต์ต่อไบต์จะ ใช้กับสคริปต์ที่โหลดใน Service Worker ผ่าน importScripts() การเปลี่ยนแปลงใดๆ ที่ทำกับสคริปต์ที่นำเข้าจะทริกเกอร์ กระบวนการอัปเดตโปรแกรมทำงานของบริการ เช่นเดียวกับที่บริการ Work Worker ระดับบนสุดทำ

ข้อมูลเบื้องต้น

ทุกครั้งที่คุณไปยังหน้าเว็บใหม่ที่อยู่ภายใต้ขอบเขตของ Service Worker ให้เรียกใช้ registration.update() อย่างชัดแจ้ง จาก JavaScript หรือเมื่อ Service Worker "ตื่น" ผ่านเหตุการณ์ push หรือ sync เบราว์เซอร์ ในขณะเดียวกันก็จะขอทรัพยากร JavaScript ที่เคยส่งผ่านไปยัง navigator.serviceWorker.register() เพื่อค้นหาอัปเดตของสคริปต์ Service Worker

สำหรับบทความนี้ สมมติว่า 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 นาที) จะไม่ส่งไปที่เครือข่าย ดังนั้น ผู้ใช้อาจไม่ได้รับโปรแกรมทำงานของบริการเวอร์ชันล่าสุด อย่างไรก็ตาม หาก max-age เป็น มากกว่า 86400 (24 ชั่วโมง) ระบบจะถือว่าเป็น 86400 เพื่อไม่ให้ผู้ใช้ติดขัด ด้วยเวอร์ชันที่เจาะจงตลอดไป

ตั้งแต่เวอร์ชัน 68 เป็นต้นไป ระบบจะไม่สนใจแคช HTTP เมื่อขออัปเดตไปยัง Service Worker ดังนั้นเว็บแอปพลิเคชันที่มีอยู่เดิมอาจเห็นว่ามีความถี่ในการส่งคำขอเพิ่มขึ้นสำหรับ สคริปต์ Service Worker คำขอสำหรับ importScripts จะยังคงดำเนินการผ่านแคช HTTP แต่นี่คือ เป็นตัวเลือกการลงทะเบียนใหม่ updateViaCache ที่มอบการควบคุม พฤติกรรมเช่นนี้

updateViaCache

ตอนนี้นักพัฒนาแอปสามารถส่งตัวเลือกใหม่เมื่อเรียกใช้ navigator.serviceWorker.register(): พารามิเตอร์ updateViaCache โดยใช้ค่าใดค่าหนึ่งจาก 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) หลังจากเริ่มต้นนั้น ดึงข้อมูล โดยเบราว์เซอร์จะจัดเก็บอยู่ภายใน และจะไม่มีการดึงข้อมูลซ้ำ

วิธีเดียวที่จะบังคับให้ Service Worker ที่ติดตั้งไว้รับการเปลี่ยนแปลง สคริปต์ที่นำเข้าคือการเปลี่ยน URL ของสคริปต์ ซึ่งโดยปกติเป็นโดยการเพิ่ม ค่าเซมเวอร์ (เช่น importScripts('https://example.com/v1.1.0/index.js')) หรือโดยการใส่แฮชของ เนื้อหานั้น (เช่น importScripts('https://example.com/index.abcd1234.js')) ต ผลข้างเคียงของการเปลี่ยน URL ที่นำเข้าคือ Service Worker ระดับสูง เนื้อหาสคริปต์จะเปลี่ยนไป ซึ่งส่งผลให้ ขั้นตอนการอัปเดตโปรแกรมทำงานของบริการ

เริ่มตั้งแต่ Chrome 78 เป็นต้นไป ทุกครั้งที่มีการตรวจหาการอัปเดตสำหรับระดับบนสุด ระบบจะทำการตรวจสอบในเวลาเดียวกันเพื่อระบุว่ามี หรือไม่เนื้อหาของสคริปต์ที่นำเข้ามามีการเปลี่ยนแปลง ขึ้นอยู่กับ ใช้ส่วนหัว Cache-Control รายการ การตรวจสอบสคริปต์ที่นำเข้าเหล่านี้อาจได้รับการดำเนินการโดย แคช HTTP หากตั้งค่า updateViaCache เป็น 'all' หรือ 'imports' (ซึ่งก็คือ ค่าเริ่มต้น) หรือการตรวจสอบอาจมีผลกับเครือข่ายโดยตรง หาก ตั้งค่า updateViaCache เป็น 'none'

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

ลักษณะการทำงานของ Chrome 78 ตรงกับสิ่งที่ Firefox implemented เมื่อหลายปีก่อนใน 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 เมื่อแสดงสคริปต์ที่มี semver หรือแฮชใน URL ของตน และใช้ลักษณะการทำงาน updateViaCache เริ่มต้นของ 'imports'

หรือถ้าคุณต้องการตรวจสอบสคริปต์ที่นำเข้าบ่อยๆ แล้วแสดงร่วมกับ Cache-Control: max-age=0 หรือที่คุณใช้ updateViaCache: 'none'

อ่านเพิ่มเติม

"วงจรของลูกค้า (Service Worker Lifecycle)" และ "แนวทางปฏิบัติแนะนำในการแคชและ max-age Gotchas", ซึ่งทั้ง 2 อย่างของ Jake Archibald แนะนำให้อ่านสำหรับนักพัฒนาซอฟต์แวร์ทั้งหมดที่ปรับใช้สิ่งต่างๆ ในเว็บ