โค้ดแล็บนี้แสดงวิธีใช้ประสบการณ์การค้นหาที่ยืดหยุ่นด้วย Workbox แอปเดโมที่แอปใช้มีช่องค้นหาที่เรียกใช้ปลายทางเซิร์ฟเวอร์ และเปลี่ยนเส้นทางผู้ใช้ไปยังหน้า HTML พื้นฐาน
วัดระยะทาง
ก่อนเพิ่มการเพิ่มประสิทธิภาพ คุณควรวิเคราะห์สถานะปัจจุบันของแอปพลิเคชันก่อน
- คลิกรีมิกซ์เพื่อแก้ไขเพื่อทำให้โปรเจ็กต์แก้ไขได้
- หากต้องการดูตัวอย่างเว็บไซต์ ให้กดดูแอป แล้วกด เต็มหน้าจอ
ในแท็บใหม่ที่เพิ่งเปิดขึ้น ให้ตรวจสอบลักษณะการทำงานของเว็บไซต์เมื่อออฟไลน์ ดังนี้
- กดแป้น Control+Shift+J (หรือ Command+Option+J ใน Mac) เพื่อเปิดเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์
- คลิกแท็บเครือข่าย
- เปิดเครื่องมือสำหรับนักพัฒนาเว็บใน Chrome แล้วเลือกแผงเครือข่าย
- ในรายการแบบเลื่อนลงของการควบคุมปริมาณ ให้เลือกออฟไลน์
- ในแอปเดโม ให้ป้อนคำค้นหาแล้วคลิกปุ่มค้นหา
หน้าข้อผิดพลาดมาตรฐานของเบราว์เซอร์จะแสดงขึ้น
ระบุคำตอบสำรอง
Service Worker มีโค้ดสำหรับเพิ่มหน้าออฟไลน์ลงในรายการแคชล่วงหน้า เพื่อให้แคชหน้าดังกล่าวได้เสมอที่เหตุการณ์ install
ของ Service Worker
โดยปกติแล้ว คุณจะต้องสั่งให้ 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()
เพื่อแสดงข้อความแจ้งสิทธิ์ของเบราว์เซอร์เริ่มต้น Promise จะแก้ไขด้วยสิทธิ์ที่ผู้ใช้เลือก ซึ่งอาจเป็นgranted
,denied
หรือdefault
- ส่งต่อสิทธิ์ที่แก้ไขแล้วให้กับ
showOfflineText()
เพื่อแสดงข้อความที่เหมาะสมแก่ผู้ใช้
เก็บการค้นหาแบบออฟไลน์ไว้และลองอีกครั้งเมื่อกลับมาออนไลน์
ถัดไป ให้ใช้การซิงค์พื้นหลังของ Workbox เพื่อเก็บการค้นหาแบบออฟไลน์ไว้ เพื่อที่จะสามารถลองอีกครั้งเมื่อเบราว์เซอร์ตรวจพบว่าการเชื่อมต่อกลับมาแล้ว
- เปิด
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
คือส่วนที่สำคัญที่สุดของโค้ดนี้ ระบบจะเรียกใช้ Callback นี้เมื่อการเชื่อมต่อกลับมาอีกครั้งเพื่อดึงข้อมูลคำขอที่อยู่ในคิวแล้วดึงข้อมูลจากเครือข่าย- ระบบจะเพิ่มการตอบกลับของเครือข่ายลงในแคช
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 มีความยืดหยุ่นและน่าสนใจมากขึ้น ในโค้ดแล็บนี้ คุณได้สำรวจวิธีใช้ Background Sync API ผ่าน Workbox Abstraction เพื่อให้แน่ใจว่าคําค้นหาของผู้ใช้แบบออฟไลน์จะไม่สูญหายและสามารถลองอีกครั้งเมื่อการเชื่อมต่อกลับมาใช้งานได้ การสาธิตเป็นแอปค้นหาง่ายๆ แต่คุณใช้การติดตั้งใช้งานที่คล้ายกันกับสถานการณ์และกรณีการใช้งานที่ซับซ้อนมากขึ้นได้ ซึ่งรวมถึงแอปรับแชท โพสต์ข้อความในโซเชียลเน็ตเวิร์ก ฯลฯ