Codelab นี้จะแสดงวิธีใช้ประสบการณ์การค้นหาที่ยืดหยุ่นด้วย 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 ค้างไว้และเลือก ล้างแคชและโหลดซ้ำถาวร เพื่อให้แน่ใจว่าได้อัปเดตโปรแกรมทำงานของบริการแล้ว
- ตั้งค่ารายการแบบเลื่อนลงการควบคุมกลับไปเป็นออฟไลน์อีกครั้ง
- ป้อนคำค้นหาแล้วคลิกปุ่มค้นหาอีกครั้ง
หน้า 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 เพื่อเก็บการค้นหาแบบออฟไลน์ไว้ เพื่อที่จะสามารถลองอีกครั้งเมื่อเบราว์เซอร์ตรวจพบว่าการเชื่อมต่อกลับมาแล้ว
- เปิด
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 ค้างไว้และเลือก ล้างแคชและโหลดซ้ำถาวร เพื่อให้แน่ใจว่าได้อัปเดตโปรแกรมทำงานของบริการแล้ว
- ตั้งค่ารายการแบบเลื่อนลงการควบคุมกลับไปเป็นออฟไลน์อีกครั้ง
- ป้อนคำค้นหาแล้วคลิกปุ่มค้นหาอีกครั้ง
- คลิกสมัครรับการแจ้งเตือน
- เมื่อ Chrome ถามคุณว่าต้องการให้สิทธิ์แอปในส่งการแจ้งเตือนไหม ให้คลิกอนุญาต
- ป้อนคำค้นหาอื่นแล้วคลิกปุ่มค้นหาอีกครั้ง
- ตั้งค่ารายการแบบเลื่อนลงการควบคุมกลับไปเป็นออนไลน์อีกครั้ง
เมื่อการเชื่อมต่อกลับมาแล้ว ระบบจะแสดงการแจ้งเตือนดังนี้
บทสรุป
Workbox มีฟีเจอร์ในตัวมากมายที่จะช่วยให้ PWA มีความยืดหยุ่นและน่าสนใจมากขึ้น ใน Codelab นี้ คุณได้สำรวจวิธีใช้ Background Sync API โดยใช้กระบวนการ Abstraction ของ Workbox เพื่อให้แน่ใจว่าคำค้นหาของผู้ใช้แบบออฟไลน์จะไม่สูญหาย และสามารถลองอีกครั้งได้เมื่อการเชื่อมต่อกลับมาแล้ว การสาธิตนี้เป็นแอปค้นหาที่เรียบง่าย แต่คุณสามารถใช้งานในลักษณะเดียวกันสำหรับสถานการณ์และกรณีการใช้งานที่ซับซ้อนมากขึ้นได้ เช่น แอปแชท การโพสต์ข้อความในโซเชียลเน็ตเวิร์ก เป็นต้น