Codelab นี้จะแสดงวิธีนำประสบการณ์การค้นหาที่ยืดหยุ่นมาปรับใช้กับ Workbox แอปเดโมที่ใช้มีช่องค้นหาที่เรียกใช้ปลายทางเซิร์ฟเวอร์ และเปลี่ยนเส้นทางผู้ใช้ไปยังหน้า HTML พื้นฐาน
วัดระยะทาง
ก่อนที่จะเพิ่มการเพิ่มประสิทธิภาพ คุณควรวิเคราะห์สถานะปัจจุบันของแอปพลิเคชันก่อน
- คลิกรีมิกซ์เพื่อแก้ไขเพื่อทำให้โปรเจ็กต์แก้ไขได้
- หากต้องการดูตัวอย่างเว็บไซต์ ให้กดดูแอป แล้วกดเต็มหน้าจอ
ในแท็บใหม่ที่เพิ่งเปิด ให้ตรวจสอบลักษณะการทำงานของเว็บไซต์เมื่อออฟไลน์
- กด "Control+Shift+J" (หรือ "Command+Option+J" ใน Mac) เพื่อเปิดเครื่องมือสำหรับนักพัฒนาเว็บ
- คลิกแท็บเครือข่าย
- เปิดเครื่องมือสำหรับนักพัฒนาเว็บใน Chrome แล้วเลือกแผงเครือข่าย
- ในรายการแบบเลื่อนลงการควบคุม ให้เลือกออฟไลน์
- ในแอปเดโม ให้ป้อนคำค้นหา แล้วคลิกปุ่มค้นหา
หน้าข้อผิดพลาดมาตรฐานของเบราว์เซอร์จะแสดงดังนี้
ระบุการตอบกลับสำรอง
โปรแกรมทำงานของบริการจะมีโค้ดสำหรับเพิ่มหน้าแบบออฟไลน์ลงในรายการแคชล่วงหน้า ดังนั้นจึงสามารถแคชไว้ในเหตุการณ์ install
ของโปรแกรมทำงานของบริการได้เสมอ
โดยปกติคุณจะต้องสั่งให้ Workbox เพิ่มไฟล์นี้ลงในรายการแคชล่วงหน้า ณ เวลาที่สร้าง โดยการผสานรวมไลบรารีกับเครื่องมือสร้างที่คุณเลือก (เช่น webpack หรือ gulp)
เราได้จัดเตรียมไว้ให้คุณแล้วเพื่อความเรียบง่าย โค้ดต่อไปนี้ที่ public/sw.js
จะดำเนินการดังกล่าว:
const FALLBACK_HTML_URL = '/index_offline.html';
…
workbox.precaching.precacheAndRoute([FALLBACK_HTML_URL]);
ต่อไป เพิ่มโค้ดเพื่อใช้หน้าแบบออฟไลน์เป็นการตอบกลับสำรอง
- หากต้องการดูแหล่งที่มา ให้กดดูแหล่งที่มา
- เพิ่มโค้ดต่อไปนี้ไว้ที่ด้านล่างของ
public/sw.js
:
workbox.routing.setDefaultHandler(new workbox.strategies.NetworkOnly());
workbox.routing.setCatchHandler(({event}) => {
switch (event.request.destination) {
case 'document':
return caches.match(FALLBACK_HTML_URL);
break;
default:
return Response.error();
}
});
โค้ดจะทำหน้าที่ดังต่อไปนี้
- กำหนดกลยุทธ์เครือข่ายเท่านั้นเริ่มต้นที่จะใช้กับคำขอทั้งหมด
- ประกาศเครื่องจัดการข้อผิดพลาดส่วนกลาง โดยเรียกใช้
workbox.routing.setCatchHandler()
เพื่อจัดการคำขอที่ล้มเหลว เมื่อเป็นคำขอสำหรับเอกสาร หน้า HTML แบบออฟไลน์สำรองจะแสดงขึ้น
หากต้องการทดสอบฟังก์ชันการทำงานนี้ ให้ทำดังนี้
- กลับไปยังแท็บอื่นที่กำลังเรียกใช้แอปของคุณ
- ตั้งค่ารายการแบบเลื่อนลงการควบคุมกลับไปเป็นออนไลน์
- กดปุ่มกลับของ Chrome เพื่อกลับไปที่หน้าค้นหา
- ตรวจสอบว่าได้ปิดใช้ช่องทำเครื่องหมายปิดใช้แคชในเครื่องมือสำหรับนักพัฒนาเว็บแล้ว
- กดปุ่มโหลดซ้ำของ Chrome ค้างไว้ แล้วเลือกล้างแคชและการโหลดซ้ำเพื่อให้มั่นใจว่า Service Worker ได้รับการอัปเดตแล้ว
- ตั้งค่ารายการแบบเลื่อนลงการควบคุมกลับไปเป็นออฟไลน์อีกครั้ง
- ป้อนคำค้นหาแล้วคลิกปุ่มค้นหาอีกครั้ง
หน้า HTML สำรองจะแสดงดังนี้
ขอสิทธิ์การแจ้งเตือน
เพื่อความง่าย หน้าออฟไลน์ที่ views/index_offline.html
มีโค้ดสำหรับขอสิทธิ์การแจ้งเตือนในบล็อกสคริปต์ที่ด้านล่างอยู่แล้ว:
function requestNotificationPermission(event) {
event.preventDefault();
Notification.requestPermission().then(function (result) {
showOfflineText(result);
});
}
โค้ดจะทำหน้าที่ดังต่อไปนี้
- เมื่อผู้ใช้คลิกสมัครรับข้อมูลการแจ้งเตือน จะมีการเรียกฟังก์ชัน
requestNotificationPermission()
ซึ่งจะเรียกNotification.requestPermission()
เพื่อแสดงข้อความแจ้งเกี่ยวกับสิทธิ์ของเบราว์เซอร์เริ่มต้น คำมั่นสัญญานี้จะจบลงด้วยสิทธิ์ที่ผู้ใช้เลือก ซึ่งอาจเป็นgranted
,denied
หรือdefault
- ผ่านสิทธิ์ที่แก้ไขแล้วไปยัง
showOfflineText()
เพื่อแสดงข้อความที่เหมาะสมแก่ผู้ใช้
คงการค้นหาแบบออฟไลน์ไว้ แล้วลองอีกครั้งเมื่อกลับมาออนไลน์
ต่อไป ให้ใช้การซิงค์พื้นหลังของ Workbox Background Sync เพื่อคงการค้นหาแบบออฟไลน์ไว้ และสามารถดำเนินการซ้ำได้เมื่อเบราว์เซอร์ตรวจพบว่าการเชื่อมต่อกลับมา
- เปิด
public/sw.js
เพื่อแก้ไข - เพิ่มโค้ดต่อไปนี้ที่ส่วนท้ายของไฟล์
const bgSyncPlugin = new workbox.backgroundSync.Plugin('offlineQueryQueue', {
maxRetentionTime: 60,
onSync: async ({queue}) => {
let entry;
while ((entry = await queue.shiftRequest())) {
try {
const response = await fetch(entry.request);
const cache = await caches.open('offline-search-responses');
const offlineUrl = `${entry.request.url}¬ification=true`;
cache.put(offlineUrl, response);
showNotification(offlineUrl);
} catch (error) {
await this.unshiftRequest(entry);
throw error;
}
}
},
});
โค้ดจะทำหน้าที่ดังต่อไปนี้
workbox.backgroundSync.Plugin
มีตรรกะในการเพิ่มคำขอที่ล้มเหลวลงในคิวเพื่อลองใหม่ในภายหลัง คำขอเหล่านี้จะคงอยู่ใน IndexedDBmaxRetentionTime
จะระบุระยะเวลาที่สามารถลองอีกครั้ง ในกรณีนี้ เราเลือกเวลา 60 นาที (หลังจากนั้นระบบจะทิ้งวิดีโอไว้)onSync
คือส่วนที่สำคัญที่สุดของโค้ดนี้ ระบบจะเรียกโค้ดเรียกกลับนี้เมื่อการเชื่อมต่อกลับมา เพื่อให้มีการเรียกคำขอที่อยู่ในคิวแล้วดึงข้อมูลจากเครือข่าย- ระบบจะเพิ่มการตอบสนองของเครือข่ายลงในแคช
offline-search-responses
โดยเพิ่มพารามิเตอร์การค้นหา¬ification=true
ต่อท้าย เพื่อให้ผู้ใช้เลือกรายการแคชนี้ได้เมื่อผู้ใช้คลิกที่การแจ้งเตือน
หากต้องการผสานรวมการซิงค์ในเบื้องหลังกับบริการของคุณ ให้กำหนดกลยุทธ์ NetworkOnly สำหรับคำขอไปยัง URL การค้นหา (/search_action
) และส่ง bgSyncPlugin
ที่กำหนดไว้ก่อนหน้านี้ เพิ่มโค้ดต่อไปนี้ไว้ที่ด้านล่างของ public/sw.js
:
const matchSearchUrl = ({url}) => {
const notificationParam = url.searchParams.get('notification');
return url.pathname === '/search_action' && !(notificationParam === 'true');
};
workbox.routing.registerRoute(
matchSearchUrl,
new workbox.strategies.NetworkOnly({
plugins: [bgSyncPlugin],
}),
);
การดำเนินการนี้จะบอกให้ Workbox ไปที่เครือข่ายเสมอ และเมื่อคำขอล้มเหลว ให้ใช้ตรรกะการซิงค์เบื้องหลัง
จากนั้นเพิ่มโค้ดต่อไปนี้ที่ด้านล่างของ public/sw.js
เพื่อกำหนดกลยุทธ์การแคชสำหรับคำขอที่มาจากการแจ้งเตือน ใช้กลยุทธ์ CacheFirst เพื่อให้แสดงจากแคชได้
const matchNotificationUrl = ({url}) => {
const notificationParam = url.searchParams.get('notification');
return (url.pathname === '/search_action' && (notificationParam === 'true'));
};
workbox.routing.registerRoute(matchNotificationUrl,
new workbox.strategies.CacheFirst({
cacheName: 'offline-search-responses',
})
);
สุดท้าย เพิ่มโค้ดเพื่อแสดงการแจ้งเตือน ดังนี้
function showNotification(notificationUrl) {
if (Notification.permission) {
self.registration.showNotification('Your search is ready!', {
body: 'Click to see you search result',
icon: '/img/workbox.jpg',
data: {
url: notificationUrl
}
});
}
}
self.addEventListener('notificationclick', function(event) {
event.notification.close();
event.waitUntil(
clients.openWindow(event.notification.data.url)
);
});
ทดสอบฟีเจอร์
- กลับไปยังแท็บอื่นที่กำลังเรียกใช้แอปของคุณ
- ตั้งค่ารายการแบบเลื่อนลงการควบคุมกลับไปเป็นออนไลน์
- กดปุ่มกลับของ Chrome เพื่อกลับไปที่หน้าค้นหา
- กดปุ่มโหลดซ้ำของ Chrome ค้างไว้ แล้วเลือกล้างแคชและการโหลดซ้ำเพื่อให้มั่นใจว่า Service Worker ได้รับการอัปเดตแล้ว
- ตั้งค่ารายการแบบเลื่อนลงการควบคุมกลับไปเป็นออฟไลน์อีกครั้ง
- ป้อนคำค้นหาแล้วคลิกปุ่มค้นหาอีกครั้ง
- คลิกติดตามการแจ้งเตือน
- เมื่อ Chrome ถามว่าคุณต้องการอนุญาตให้แอปส่งการแจ้งเตือนหรือไม่ ให้คลิกอนุญาต
- ป้อนคำค้นหาอื่นแล้วคลิกปุ่มค้นหาอีกครั้ง
- ตั้งค่ารายการแบบเลื่อนลงการควบคุมกลับไปเป็นออนไลน์อีกครั้ง
เมื่อเชื่อมต่ออีกครั้งแล้ว ระบบจะแสดงการแจ้งเตือนดังนี้
บทสรุป
Workbox มีฟีเจอร์ในตัวมากมายที่ทำให้ PWA มีความยืดหยุ่นและน่าสนใจยิ่งขึ้น ใน Codelab นี้ คุณได้ศึกษาวิธีใช้ Background Sync API โดยใช้ระบบ Abstraction ของ Workbox เพื่อให้แน่ใจว่าการค้นหาของผู้ใช้แบบออฟไลน์จะไม่สูญหาย และสามารถลองอีกครั้งได้เมื่อกลับมาเชื่อมต่ออีกครั้ง เดโมนี้เป็นแอปการค้นหาที่ใช้งานง่าย แต่คุณสามารถใช้การติดตั้งใช้งานที่คล้ายกันสำหรับสถานการณ์และกรณีการใช้งานที่ซับซ้อนมากขึ้น ซึ่งรวมถึงแอปแชท การโพสต์ข้อความในโซเชียลเน็ตเวิร์ก เป็นต้น