Codelab นี้เป็นส่วนหนึ่งของหลักสูตรการฝึกอบรม Progressive Web App ที่พัฒนาโดยทีมการฝึกอบรมของ Google Developers คุณจะได้ประโยชน์สูงสุดจากหลักสูตรนี้หากคุณทํางานผ่าน Codelab ตามลําดับ
โปรดดูรายละเอียดทั้งหมดเกี่ยวกับหลักสูตรที่หัวข้อการพัฒนา Progressive Web App
บทนำ
ห้องทดลองนี้จะแนะนําวิธีสร้าง Service Worker แบบง่ายๆ และอธิบายถึงวงจรชีวิตของ Service Worker
สิ่งที่คุณจะได้เรียนรู้
- สร้างสคริปต์ Service Worker พื้นฐาน ติดตั้ง และแก้ไขข้อบกพร่องแบบง่ายๆ
สิ่งที่ควรทราบ
- JavaScript และ HTML พื้นฐาน
- แนวคิดและไวยากรณ์พื้นฐานของคําสัญญา ES2015
- วิธีเปิดใช้ Play Console
สิ่งที่ต้องมีก่อนเริ่มต้น
- คอมพิวเตอร์ที่มีสิทธิ์เข้าถึงเทอร์มินัล/Shell
- การเชื่อมต่ออินเทอร์เน็ต
- เบราว์เซอร์ที่รองรับ Service Worker
- เครื่องมือแก้ไขข้อความ
ดาวน์โหลดหรือโคลนที่เก็บ pwa-training-labs จาก github และติดตั้ง Node.js เวอร์ชัน LTS
ไปที่ไดเรกทอรี service-worker-lab/app/
แล้วเริ่มต้นเซิร์ฟเวอร์การพัฒนาในเครื่อง:
cd service-worker-lab/app npm install node server.js
คุณจะยกเลิกเซิร์ฟเวอร์ได้ตลอดเวลาด้วย Ctrl-c
เปิดเบราว์เซอร์แล้วไปที่ localhost:8081/
หมายเหตุ: ยกเลิกการลงทะเบียน Service Worker และล้างแคชของ Service Worker ทั้งหมดสําหรับ Localhost เพื่อไม่ให้รบกวนห้องทดลอง ใน Chrome DevTools คุณจะดําเนินการได้โดยการคลิกล้างข้อมูลเว็บไซต์จากส่วนล้างพื้นที่เก็บข้อมูลของแท็บแอปพลิเคชัน
เปิดโฟลเดอร์ service-worker-lab/app/
ในเครื่องมือแก้ไขข้อความที่ต้องการ โฟลเดอร์ app/
คือที่ที่คุณจะสร้างห้องทดลอง
โฟลเดอร์นี้มีสิ่งต่อไปนี้
below/another.html
,js/another.js
,js/other.js
และother.html
เป็นทรัพยากรตัวอย่างที่เราใช้ทดสอบกับขอบเขต Service Worker- โฟลเดอร์
styles/
มีสไตล์ชีตแบบแคชสําหรับห้องทดลองนี้ test/
โฟลเดอร์มีไฟล์สําหรับการทดสอบความคืบหน้าของคุณindex.html
เป็นหน้า HTML หลักสําหรับเว็บไซต์/แอปพลิเคชันตัวอย่างของเราservice-worker.js
คือไฟล์ JavaScript ที่ใช้สร้าง Service Workerpackage.json
และpackage-lock.json
จะติดตามแพ็กเกจโหนดที่ใช้ในโปรเจ็กต์นี้server.js
เป็นเซิร์ฟเวอร์ด่วนแบบง่ายๆ ที่เราใช้เพื่อโฮสต์แอป
เปิด service-worker.js
ในเครื่องมือแก้ไขข้อความ โปรดทราบว่าไฟล์ว่างเปล่า เรายังไม่ได้เพิ่มโค้ดที่จะเรียกใช้ภายใน Service Worker
เปิด index.html
ในเครื่องมือแก้ไขข้อความ
ในแท็ก <script>
ให้เพิ่มโค้ดต่อไปนี้เพื่อลงทะเบียน Service Worker
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('service-worker.js')
.then(registration => {
console.log('Service Worker is registered', registration);
})
.catch(err => {
console.error('Registration failed:', err);
});
});
}
บันทึกสคริปต์และรีเฟรชหน้า คอนโซลควรส่งข้อความที่ระบุว่ามีการลงทะเบียน Service Worker แล้ว ใน Chrome คุณตรวจสอบได้ว่ามี Service Worker ลงทะเบียนอยู่หรือไม่โดยเปิด DevTools (Control + Shift + I ใน Windows และ Linux หรือ ⌘ + Alt + I ใน Mac) จากนั้นคลิกแท็บแอปพลิเคชัน แล้วคลิกตัวเลือก Service Worker คุณควรเห็นข้อมูลที่มีลักษณะคล้ายกับด้านล่าง
ไม่บังคับ: เปิดเว็บไซต์ในเบราว์เซอร์ที่ไม่รองรับ และตรวจสอบว่าทีมสนับสนุนตรวจสอบแบบมีเงื่อนไข
คำอธิบาย
โค้ดด้านบนจะลงทะเบียนไฟล์ service-worker.js
เป็น Service Worker ขั้นแรกให้ตรวจสอบก่อนว่าเบราว์เซอร์รองรับ Service Worker หรือไม่ ควรทําเช่นนี้ทุกครั้งที่คุณลงทะเบียน Service Worker เนื่องจากเบราว์เซอร์บางรายการอาจไม่รองรับ Service Worker จากนั้นโค้ดจะลงทะเบียน Service Worker โดยใช้เมธอด register
ของ ServiceWorkerContainer
API ซึ่งอยู่ในอินเทอร์เฟซของ Navigator
ของหน้าต่าง
navigator.serviceWorker.register(...)
จะส่งคืนคําสัญญาที่แก้ไขด้วยออบเจ็กต์ registration
เมื่อลงทะเบียน Service Worker เรียบร้อยแล้ว หากจดทะเบียนไม่สําเร็จ สัญญาจะปฏิเสธ
การเปลี่ยนแปลงสถานะของ Service Worker ทําให้ Service Worker ทํางาน
เพิ่ม Listener เหตุการณ์
เปิด service-worker.js
ในเครื่องมือแก้ไขข้อความ
เพิ่ม Listener เหตุการณ์ต่อไปนี้ให้กับ Service Worker
self.addEventListener('install', event => {
console.log('Service worker installing...');
// Add a call to skipWaiting here
});
self.addEventListener('activate', event => {
console.log('Service worker activating...');
});
บันทึกไฟล์
ยกเลิกการลงทะเบียน Service Worker ด้วยตนเองและรีเฟรชหน้าเพื่อติดตั้งและเปิดใช้งาน Service Worker ที่อัปเดต บันทึกของคอนโซลควรระบุว่ามีการลงทะเบียน ติดตั้ง และเปิดใช้งาน Service Worker ใหม่แล้ว
หมายเหตุ: บันทึกการจดทะเบียนอาจปรากฏขึ้นร่วมกับบันทึกอื่นๆ (การติดตั้งและการเปิดใช้งาน) Service Worker ทํางานร่วมกับหน้าเว็บพร้อมๆ กัน ดังนั้นเราจึงไม่สามารถรับประกันลําดับของบันทึกได้ (บันทึกการลงทะเบียนจะมาจากหน้าเว็บ ในขณะที่บันทึกการติดตั้งและการเปิดใช้งานมาจาก Service Worker) อย่างไรก็ตาม การติดตั้ง การเปิดใช้งาน และเหตุการณ์อื่นๆ ของ Service Worker จะเกิดขึ้นตามลําดับที่กําหนดไว้ภายใน Service Worker และควรปรากฏตามลําดับที่คาดไว้เสมอ
คำอธิบาย
Service Worker จะส่งเหตุการณ์ install
เมื่อสิ้นสุดการลงทะเบียน ในโค้ดด้านบน ข้อความจะบันทึกอยู่ใน Listener เหตุการณ์ install
แต่ในแอปที่ดีนี้เป็นพื้นที่ที่เหมาะสําหรับการแคชเนื้อหาแบบคงที่
เมื่อลงทะเบียน Service Worker แล้ว เบราว์เซอร์จะตรวจสอบว่า Service Worker เป็นผู้ใช้ใหม่หรือไม่ (เพราะแตกต่างจาก Service Worker ที่ติดตั้งไว้ก่อนหน้านี้ หรือเพราะไม่มี Service Worker ที่ลงทะเบียนสําหรับเว็บไซต์นี้) หาก Service Worker เป็นเวอร์ชันใหม่ (ตามที่เป็นในกรณีนี้) เบราว์เซอร์จะติดตั้ง Service Worker อีกครั้ง
Service Worker จะส่งเหตุการณ์ activate
เมื่อเข้าควบคุมหน้า โค้ดด้านบนจะบันทึกข้อความที่นี่ แต่เหตุการณ์นี้มักจะใช้ในการอัปเดตแคช
ใช้งาน Service Worker ได้ครั้งละ 1 คนเท่านั้นสําหรับขอบเขตที่ระบุ (ดูขอบเขต Service Worker ) ดังนั้น Service Worker ที่ติดตั้งใหม่จะยังไม่เปิดใช้งานจนกว่า Service Worker ที่มีอยู่จะใช้งานไม่ได้อีกต่อไป ซึ่งเป็นเหตุให้ต้องปิดหน้าเว็บทั้งหมดที่ควบคุมโดย Service Worker ก่อนที่ Service Worker ใหม่จะเข้ามาแทนที่ได้ เนื่องจากเรายกเลิกการลงทะเบียน Service Worker ที่มีอยู่ มีการเปิดใช้งาน Service Worker ใหม่ทันที
หมายเหตุ: การรีเฟรชหน้าไม่เพียงพอที่จะโอนการควบคุมไปยัง Service Worker ใหม่ได้เนื่องจากระบบจะขอหน้าใหม่ก่อนโหลดหน้าปัจจุบัน และจะ "ไม่มี" เวลาที่ไม่มีการใช้งาน Service Worker เก่า
หมายเหตุ: คุณยังสามารถเปิดใช้งาน Service Worker ใหม่โดยใช้เบราว์เซอร์บางตัวและเครื่องมือสําหรับนักพัฒนาซอฟต์แวร์ และทํางานกับ skipWaiting()
แบบเป็นโปรแกรมได้ ซึ่งเราจะพูดถึงในส่วนที่ 3.4
อัปเดต Service Worker
เพิ่มความคิดเห็นต่อไปนี้ที่ใดก็ได้ใน service-worker.js
// I'm a new service worker
บันทึกไฟล์และรีเฟรชหน้า ดูบันทึกในคอนโซลโดยสังเกตว่า Service Worker ใหม่ติดตั้งแล้วแต่ไม่ได้เปิดใช้งาน คุณดู Chrome Service Worker ใน Chrome ได้ในแท็บแอปพลิเคชันในเครื่องมือสําหรับนักพัฒนาเว็บ
ปิดหน้าเว็บทั้งหมดที่เชื่อมโยงกับ Service Worker จากนั้นเปิด localhost:8081/
อีกครั้ง บันทึกของคอนโซลควรระบุว่ามีการเปิดใช้งาน Service Worker ใหม่แล้ว
หมายเหตุ: หากคุณได้รับผลลัพธ์ที่ไม่คาดคิด ให้ตรวจสอบว่าแคช HTTP ถูกปิดใช้ในเครื่องมือสําหรับนักพัฒนาซอฟต์แวร์
คำอธิบาย
เบราว์เซอร์จะตรวจพบความแตกต่าง 1 ไบต์ระหว่างไฟล์บริการใหม่กับ Service Worker ที่มีอยู่ (เนื่องจากมีความคิดเห็นที่เพิ่มเข้ามา) เพื่อให้มีการติดตั้ง Service Worker ใหม่ เนื่องจากสามารถใช้ Service Worker ได้ครั้งละ 1 คนเท่านั้น (ตามขอบเขตที่กําหนด) แม้ว่าจะติดตั้ง Service Worker ใหม่แล้ว พนักงานก็จะยังไม่เปิดใช้งานจนกว่า Service Worker ที่มีอยู่จะใช้งานไม่ได้อีกต่อไป เราปิด Service Worker ใหม่ๆ ได้ภายใต้การควบคุมของ Service Worker แบบเก่าแล้ว
ข้ามช่วงรอ
อาจมี Service Worker รายใหม่เปิดใช้งานได้ทันที แม้ว่าจะมี Service Worker เดิมอยู่ก็ตามโดยข้ามช่วงรอ
ใน service-worker.js
ให้เพิ่มการเรียกใช้ไปยัง skipWaiting
ใน Listener เหตุการณ์ install
self.skipWaiting();
บันทึกไฟล์และรีเฟรชหน้า โปรดสังเกตว่า Service Worker ใหม่จะติดตั้งและเปิดใช้งานทันที แม้ว่าจะยังมีคนควบคุมบริการก่อนหน้านี้อยู่
คำอธิบาย
เมธอด skipWaiting()
ช่วยให้ Service Worker ทํางานได้ทันทีที่ติดตั้งเสร็จ Listener เหตุการณ์การติดตั้งเป็นพื้นที่ทั่วไปสําหรับเรียกใช้ skipWaiting()
แต่จะเรียกใช้ได้ทุกที่ในระหว่างหรือก่อนระยะรอ ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีใช้ skipWaiting()
ในเอกสารนี้ สําหรับส่วนที่เหลือของห้องทดลอง ตอนนี้เราทดสอบโค้ด Service Worker ใหม่ได้โดยไม่ต้องยกเลิกการลงทะเบียน Service Worker ด้วยตนเองแล้ว
หากต้องการข้อมูลเพิ่มเติม
Service Worker เป็นพร็อกซีระหว่างเว็บแอปกับเครือข่ายของคุณได้
มาเพิ่ม Listener การดึงข้อมูลเพื่อสกัดกั้นคําขอจากโดเมนของเรากัน
เพิ่มโค้ดต่อไปนี้ลงใน service-worker.js
self.addEventListener('fetch', event => {
console.log('Fetching:', event.request.url);
});
บันทึกสคริปต์และรีเฟรชหน้าเว็บเพื่อติดตั้งและเปิดใช้งาน Service Worker ที่อัปเดต
ตรวจสอบคอนโซลและสังเกตว่าไม่มีเหตุการณ์การดึงข้อมูล รีเฟรชหน้านี้และตรวจสอบคอนโซลอีกครั้ง ขณะนี้คุณควรเห็นเหตุการณ์การดึงข้อมูลหน้าเว็บและเนื้อหาในหน้า (เช่น CSS)
คลิกลิงก์ไปยังหน้าอื่นๆ หน้าอื่น และกลับ
คุณจะเห็นเหตุการณ์การดึงข้อมูลในคอนโซลสําหรับแต่ละหน้าและเนื้อหาในหน้า บันทึกทั้งหมดเหมาะสมไหม
หมายเหตุ: หากคุณเข้าชมหน้าเว็บและไม่ได้ปิดใช้แคช HTTP เนื้อหา CSS และ JavaScript อาจถูกแคชไว้ในเครื่อง ในกรณีนี้ คุณจะไม่เห็นเหตุการณ์การดึงข้อมูลสําหรับทรัพยากรเหล่านี้
คำอธิบาย
Service Worker จะได้รับเหตุการณ์การดึงข้อมูลสําหรับคําขอ HTTP ทั้งหมดที่มาจากเบราว์เซอร์ที่อยู่ในขอบเขตของโปรแกรม ออบเจ็กต์ fetch event มีคําขอ การฟังเหตุการณ์การดึงข้อมูลใน Service Worker คล้ายกับการฟังเหตุการณ์การคลิกใน DOM ในโค้ดของเรา เมื่อมีเหตุการณ์การดึงข้อมูลเกิดขึ้น เราจะบันทึก URL ที่ขอไปยังคอนโซลผู้ดูแลระบบ (ในทางปฏิบัติ เราสร้างและส่งคืนการตอบกลับที่กําหนดเองของเราด้วยทรัพยากรที่กําหนดเองได้)
เหตุใดจึงไม่มีการบันทึกเหตุการณ์การดึงข้อมูลในการรีเฟรชครั้งแรก โดยค่าเริ่มต้น การดึงข้อมูลเหตุการณ์จากหน้าเว็บจะไม่ผ่าน Service Worker เว้นแต่ตัวคําขอหน้าเว็บจะดําเนินการผ่าน Service Worker การดําเนินการนี้จะช่วยให้เว็บไซต์ของคุณสอดคล้องกัน หากหน้าเว็บโหลดโดยไม่มี Service Worker ทรัพยากรย่อยก็จะโหลดด้วย
หากต้องการข้อมูลเพิ่มเติม
- เหตุการณ์การดึงข้อมูล - MDN
- การใช้การดึงข้อมูล - MDN
- ข้อมูลเบื้องต้นเกี่ยวกับการดึงข้อมูล - นักพัฒนาซอฟต์แวร์ Google
โค้ดโซลูชัน
หากต้องการทําสําเนารหัสที่ใช้งานได้ ให้ไปที่โฟลเดอร์ 04-intercepting-network-requests/
Service Worker มีขอบเขต ขอบเขตของ Service Worker เป็นตัวกําหนดเส้นทางการสกัดกั้นของ Service Worker
ค้นหาขอบเขต
อัปเดตรหัสการลงทะเบียนใน index.html
ด้วย
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('service-worker.js')
.then(registration => {
console.log('SW registered with scope:', registration.scope);
})
.catch(err => {
console.error('Registration failed:', err);
});
});
}
รีเฟรชเบราว์เซอร์ โปรดสังเกตว่าคอนโซลแสดงขอบเขต Service Worker (ในกรณีนี้คือ http://localhost:8081/
)
คำอธิบาย
สัญญาที่ได้จาก register()
จะแปลงเป็นออบเจ็กต์การลงทะเบียน ซึ่งมีขอบเขต Service Worker
ขอบเขตเริ่มต้นคือเส้นทางไปยังไฟล์ Service Worker และขยายไปยังไดเรกทอรีที่ต่ํากว่าทั้งหมด ดังนั้น Service Worker ในไดเรกทอรีรากของแอปจะควบคุมคําขอจากไฟล์ทั้งหมดในแอป
ย้าย Service Worker
ย้าย service-worker.js
ไปยังไดเรกทอรี below/
และอัปเดต URL ของ Service Worker ในโค้ดการลงทะเบียนใน index.html
ยกเลิกการลงทะเบียน Service Worker ปัจจุบันในเบราว์เซอร์และรีเฟรชหน้า
คอนโซลจะแสดงว่าขอบเขตของ Service Worker อยู่ที่ http://localhost:8081/below/
คุณยังดูขอบเขต Service Worker ใน Chrome แอปพลิเคชันแอปพลิเคชันของ DevTools ได้ใน Chrome
กลับไปที่หน้าหลัก คลิกหน้าอื่นๆ หน้าอื่น และกลับ คําขอดึงข้อมูลใดได้รับการบันทึกอยู่ ในข้อใดไม่ใช่ #39
คำอธิบาย
ขอบเขตเริ่มต้นของ Service Worker คือเส้นทางไปยังไฟล์ Service Worker เนื่องจากไฟล์ Service Worker อยู่ใน below/
ขอบเขตจึงเป็น ขณะนี้คอนโซลจะบันทึกเหตุการณ์การดึงข้อมูลสําหรับ another.html
, another.css
และ another.js
เท่านั้น เนื่องจากทรัพยากรเหล่านี้มีเพียงทรัพยากรเดียวภายในขอบเขต Service Worker
กําหนดขอบเขตที่กําหนดเอง
ย้าย Service Worker กลับไปที่ไดเรกทอรีรากของโปรเจ็กต์ (app/
) และอัปเดต URL ของ Service Worker ในโค้ดการลงทะเบียนใน index.html
ใช้การอ้างอิง MDN เพื่อตั้งค่าขอบเขตของ Service Worker ไปยังไดเรกทอรี below/
โดยใช้พารามิเตอร์ที่ไม่บังคับใน register()
ยกเลิกการลงทะเบียน Service Worker และรีเฟรชหน้า คลิกหน้าอื่นๆ หน้าอื่น และกลับ
เช่นเดียวกัน คอนโซลนี้แสดงว่าขอบเขตของ Service Worker เท่ากับ http://localhost:8081/below/
และบันทึกเหตุการณ์การดึงข้อมูลสําหรับ another.html
, another.css
และ another.js
เท่านั้น
คำอธิบาย
คุณสามารถตั้งค่าขอบเขตที่กําหนดเองได้โดยส่งพารามิเตอร์เพิ่มเติมขณะลงทะเบียน ตัวอย่างเช่น
navigator.serviceWorker.register('/service-worker.js', {
scope: '/kitten/'
});
ในตัวอย่างข้างต้น ขอบเขตของ Service Worker ตั้งไว้เป็น /kitten/
Service Worker จะสกัดกั้นคําขอจากหน้าใน /kitten/
และ /kitten/lower/
แต่ไม่จากหน้าต่างๆ เช่น /kitten
หรือ /
หมายเหตุ: คุณไม่สามารถตั้งขอบเขตที่กําหนดเองซึ่งอยู่เหนือตําแหน่งจริงของ Service Worker อย่างไรก็ตาม หากผู้ปฏิบัติงานเซิร์ฟเวอร์ของคุณทํางานในไคลเอ็นต์ที่กําลังแสดงผลด้วยส่วนหัว Service-Worker-Allowed
คุณจะระบุขอบเขตสูงสุดสําหรับ Service Worker เหนือตําแหน่งของ Service Worker ได้
หากต้องการข้อมูลเพิ่มเติม
โค้ดโซลูชัน
หากต้องการทําสําเนารหัสที่ใช้งานได้ ให้ไปที่โฟลเดอร์ solution/
ตอนนี้คุณจะมี Service Worker ที่ไม่ซับซ้อนและเริ่มใช้งาน รวมถึงทําความเข้าใจวงจรการทํางานของ Service Worker
หากต้องการข้อมูลเพิ่มเติม
ดู Codelab ทั้งหมดในหลักสูตรการฝึกอบรม PWA ที่หัวข้อยินดีต้อนรับ Codelab ของหลักสูตร/