การเปิดใช้ Service Worker เพื่อบอกเบราว์เซอร์ว่าหน้าใดทำงานแบบออฟไลน์ได้
Content Indexing API คืออะไร
การใช้ Progressive Web App หมายความว่าคุณมีสิทธิ์เข้าถึงข้อมูลที่สำคัญต่อผู้ใช้ เช่น รูปภาพ วิดีโอ บทความ และอื่นๆ ไม่ว่าสถานะการเชื่อมต่อเครือข่ายของคุณจะเป็นอย่างไร เทคโนโลยีต่างๆ เช่น Service Worker, Cache Storage API และ IndexedDB เป็นองค์ประกอบพื้นฐานในการจัดเก็บและแสดงข้อมูลเมื่อผู้ใช้โต้ตอบกับ PWA โดยตรง แต่การสร้าง PWA ที่มีคุณภาพสูงและเน้นการทำงานแบบออฟไลน์เป็นหลักเป็นเพียงส่วนหนึ่งของเรื่องราวเท่านั้น หากผู้ใช้ไม่ทราบว่าเนื้อหาของเว็บแอปพร้อมใช้งานขณะออฟไลน์ ผู้ใช้ก็จะไม่ใช้ประโยชน์จากการทำงานที่คุณทุ่มเทให้กับการใช้งานฟังก์ชันการทำงานนั้นอย่างเต็มที่
ปัญหานี้เกี่ยวข้องกับการค้นพบ PWA ของคุณจะทําให้ผู้ใช้ทราบถึงเนื้อหาที่พร้อมใช้งานแบบออฟไลน์ได้อย่างไรเพื่อให้ผู้ใช้ค้นพบและดูเนื้อหาที่พร้อมใช้งาน Content Indexing API คือโซลูชันสําหรับปัญหานี้ ส่วนที่เป็นหน้าสำหรับนักพัฒนาแอปของโซลูชันนี้คือส่วนขยายของ Service Worker ซึ่งช่วยให้นักพัฒนาแอปเพิ่ม URL และข้อมูลเมตาของหน้าเว็บที่ใช้งานแบบออฟไลน์ได้ลงในดัชนีในเครื่องที่เบราว์เซอร์ดูแลรักษา การเพิ่มประสิทธิภาพดังกล่าวพร้อมใช้งานใน Chrome เวอร์ชัน 84 ขึ้นไป
เมื่อดัชนีมีเนื้อหาจาก PWA ของคุณ รวมถึง PWA อื่นๆ ที่ติดตั้งไว้แล้ว เบราว์เซอร์จะแสดงดัชนีดังกล่าวดังที่แสดงด้านล่าง
นอกจากนี้ Chrome ยังแนะนำเนื้อหาได้เมื่อตรวจพบว่าผู้ใช้ออฟไลน์อยู่
Content Indexing API ไม่ใช่วิธีอื่นในการแคชเนื้อหา ซึ่งเป็นวิธีระบุข้อมูลเมตาเกี่ยวกับหน้าที่ Service Worker แคชไว้แล้ว เพื่อให้เบราว์เซอร์แสดงหน้าเหล่านั้นเมื่อผู้ใช้มีแนวโน้มที่จะต้องการดู Content Indexing API ช่วยเรื่องการค้นพบหน้าเว็บที่แคชไว้
ดูของจริง
วิธีที่ดีที่สุดในการลองใช้ Content Indexing API คือลองใช้แอปพลิเคชันตัวอย่าง
- ตรวจสอบว่าคุณใช้เบราว์เซอร์และแพลตฟอร์มที่รองรับ ปัจจุบันฟีเจอร์นี้ใช้ได้เฉพาะใน Chrome 84 ขึ้นไปใน Android ไปที่
about://version
เพื่อดูว่าคุณใช้ Chrome เวอร์ชันใด - ไปที่ https://contentindex.dev
- คลิกปุ่ม
+
ข้างรายการอย่างน้อย 1 รายการในรายการ - (ไม่บังคับ) ปิดใช้การเชื่อมต่อ Wi-Fi และอินเทอร์เน็ตมือถือของอุปกรณ์ หรือเปิดใช้โหมดบนเครื่องบินเพื่อจำลองการทำให้เบราว์เซอร์ออฟไลน์
- เลือกรายการที่ดาวน์โหลดจากเมนูของ Chrome แล้วเปลี่ยนไปใช้แท็บบทความสำหรับคุณ
- เรียกดูเนื้อหาที่คุณบันทึกไว้ก่อนหน้านี้
คุณดูแหล่งที่มาของแอปพลิเคชันตัวอย่างใน GitHub ได้
แอปพลิเคชันตัวอย่างอีกรายการหนึ่งคือ Scrapbook PWA ซึ่งแสดงการใช้ Content Indexing API กับ Web Share Target API โค้ดแสดงเทคนิคในการทำให้ Content Indexing API ซิงค์กับรายการที่เว็บแอปจัดเก็บโดยใช้ Cache Storage API
การใช้ API
หากต้องการใช้ API แอปของคุณต้องมี Service Worker และ URL ที่ไปยังส่วนต่างๆ ได้แบบออฟไลน์ หากตอนนี้เว็บแอปของคุณไม่มี Service Worker ไลบรารี Workbox จะช่วยให้สร้าง Service Worker ได้ง่ายขึ้น
URL ประเภทใดบ้างที่จัดทําดัชนีได้ว่าเป็น URL ที่ใช้งานได้แบบออฟไลน์
API รองรับการจัดทําดัชนี URL ที่สอดคล้องกับเอกสาร HTML เช่น URL ของไฟล์สื่อที่แคชไว้จะจัดทำดัชนีโดยตรงไม่ได้ แต่คุณต้องระบุ URL ของหน้าเว็บที่แสดงสื่อและใช้งานได้แบบออฟไลน์แทน
รูปแบบที่แนะนำคือสร้างหน้า HTML "โปรแกรมดู" ที่ยอมรับ URL ของสื่อพื้นฐานเป็นพารามิเตอร์การค้นหา แล้วแสดงเนื้อหาของไฟล์ โดยอาจมีการควบคุมหรือเนื้อหาเพิ่มเติมในหน้า
เว็บแอปจะเพิ่ม URL ลงในดัชนีเนื้อหาได้เฉพาะ URL ที่อยู่ภายใต้ขอบเขตของ Service Worker ปัจจุบัน กล่าวคือ เว็บแอปไม่สามารถเพิ่ม URL ของโดเมนอื่นที่แตกต่างออกไปลงในดัชนีเนื้อหาได้
ภาพรวม
Content Indexing API รองรับการดำเนินการ 3 รายการ ได้แก่ การเพิ่ม แสดง และนำข้อมูลเมตาออก เมธอดเหล่านี้แสดงจากพร็อพเพอร์ตี้ใหม่ index
ที่เพิ่มลงในอินเทอร์เฟซ ServiceWorkerRegistration
ขั้นตอนแรกในการจัดทําดัชนีเนื้อหาคือการรับข้อมูลอ้างอิงถึง ServiceWorkerRegistration
ปัจจุบัน การใช้ navigator.serviceWorker.ready
เป็นวิธีที่ตรงที่สุด
const registration = await navigator.serviceWorker.ready;
// Remember to feature-detect before using the API:
if ('index' in registration) {
// Your Content Indexing API code goes here!
}
หากคุณเรียกใช้ Content Indexing API จากภายใน Service Worker แทนที่จะเป็นในหน้าเว็บ คุณสามารถอ้างอิง ServiceWorkerRegistration
ได้โดยตรงผ่าน registration
ระบบจะกําหนดไว้แล้วเป็นส่วนหนึ่งของ ServiceWorkerGlobalScope.
การเพิ่มลงในดัชนี
ใช้เมธอด add()
เพื่อจัดทำดัชนี URL และข้อมูลเมตาที่เกี่ยวข้อง คุณเลือกได้ว่าจะเพิ่มรายการลงในดัชนีเมื่อใด คุณอาจต้องการเพิ่มลงในดัชนีเพื่อตอบสนองต่ออินพุต เช่น การคลิกปุ่ม "บันทึกแบบออฟไลน์" หรือคุณอาจเพิ่มรายการโดยอัตโนมัติทุกครั้งที่มีการอัปเดตข้อมูลที่แคชไว้ผ่านกลไกต่างๆ เช่น การซิงค์ในเบื้องหลังเป็นระยะ
await registration.index.add({
// Required; set to something unique within your web app.
id: 'article-123',
// Required; url needs to be an offline-capable HTML page.
url: '/articles/123',
// Required; used in user-visible lists of content.
title: 'Article title',
// Required; used in user-visible lists of content.
description: 'Amazing article about things!',
// Required; used in user-visible lists of content.
icons: [{
src: '/img/article-123.png',
sizes: '64x64',
type: 'image/png',
}],
// Optional; valid categories are currently:
// 'homepage', 'article', 'video', 'audio', or '' (default).
category: 'article',
});
การเพิ่มรายการจะส่งผลต่อดัชนีเนื้อหาเท่านั้น โดยจะไม่เพิ่มข้อมูลใดๆ ลงในแคช
กรณีสุดโต่ง: เรียก add()
จากบริบท window
หากไอคอนใช้ตัวแฮนเดิล fetch
เมื่อคุณเรียกใช้ add()
แล้ว Chrome จะส่งคำขอ URL ของไอคอนแต่ละรายการเพื่อให้แน่ใจว่ามีสำเนาของไอคอนที่จะใช้เมื่อแสดงรายการเนื้อหาที่จัดทําดัชนี
หากคุณเรียกใช้
add()
จากบริบทwindow
(กล่าวคือ จากหน้าเว็บ) คำขอนี้จะทริกเกอร์เหตุการณ์fetch
ใน Service Workerหากคุณเรียกใช้
add()
ภายใน Service Worker (อาจอยู่ภายในตัวแฮนเดิลเหตุการณ์อื่น) คำขอจะไม่ทริกเกอร์ตัวแฮนเดิลfetch
ของ Service Worker ระบบจะดึงข้อมูลไอคอนโดยตรงโดยไม่ต้องมี Service Worker ใดๆ เข้ามาเกี่ยวข้อง โปรดคำนึงถึงเรื่องนี้หากไอคอนใช้ตัวแฮนเดิลfetch
ซึ่งอาจเป็นเพราะไอคอนเหล่านั้นอยู่ในแคชในเครื่องเท่านั้นและไม่ได้อยู่ในเครือข่าย หากมี ให้ตรวจสอบว่าคุณเรียกใช้add()
จากบริบทwindow
เท่านั้น
แสดงรายการเนื้อหาของดัชนี
เมธอด getAll()
จะแสดงผลพรอมต์สำหรับรายการรายการที่จัดทำดัชนีและข้อมูลเมตาของรายการเหล่านั้นซึ่งวนซ้ำได้ รายการที่แสดงจะมีข้อมูลทั้งหมดที่บันทึกไว้กับ add()
const entries = await registration.index.getAll();
for (const entry of entries) {
// entry.id, entry.launchUrl, etc. are all exposed.
}
การนำรายการออกจากดัชนี
หากต้องการนำรายการออกจากดัชนี ให้เรียกใช้ delete()
พร้อม id
ของรายการที่จะนำออก
await registration.index.delete('article-123');
การเรียกใช้ delete()
จะมีผลกับดัชนีเท่านั้น การดำเนินการนี้จะไม่ลบข้อมูลใดๆ ออกจากแคช
การจัดการเหตุการณ์การลบของผู้ใช้
เมื่อเบราว์เซอร์แสดงเนื้อหาที่จัดทำดัชนีแล้ว อาจมีอินเทอร์เฟซผู้ใช้ของตัวเองที่มีรายการเมนูลบ ซึ่งช่วยให้ผู้ใช้ระบุได้ว่าดูเนื้อหาที่จัดทำดัชนีไว้ก่อนหน้านี้เสร็จแล้ว อินเทอร์เฟซการลบใน Chrome 80 มีหน้าตาดังนี้
เมื่อมีผู้เลือกรายการเมนูดังกล่าว เวิร์กเกอร์บริการของเว็บแอปของคุณจะได้รับเหตุการณ์ contentdelete
แม้ว่าการจัดการเหตุการณ์นี้จะไม่ใช่สิ่งจําเป็น แต่จะช่วยให้ Service Worker มีเวลา "ล้างข้อมูล" เนื้อหา เช่น ไฟล์สื่อที่แคชไว้ในพื้นที่ ซึ่งผู้ใช้ระบุว่าใช้งานเสร็จแล้ว
คุณไม่จําเป็นต้องเรียก registration.index.delete()
ในตัวแฮนเดิล contentdelete
เนื่องจากเบราว์เซอร์จะลบดัชนีที่เกี่ยวข้องหากมีการเรียกเหตุการณ์
self.addEventListener('contentdelete', (event) => {
// event.id will correspond to the id value used
// when the indexed content was added.
// Use that value to determine what content, if any,
// to delete from wherever your app stores it—usually
// the Cache Storage API or perhaps IndexedDB.
});
ความคิดเห็นเกี่ยวกับการออกแบบ API
API มีข้อใดที่ทำให้คุณไม่สะดวกหรือทำงานไม่เป็นไปตามที่คาดไว้ไหม หรือมีชิ้นส่วนที่ขาดหายไปซึ่งคุณต้องนำมาใช้เพื่อนำแนวคิดของคุณไปปฏิบัติจริง
แจ้งปัญหาในที่เก็บ GitHub ของคำอธิบาย Content Indexing API หรือแสดงความคิดเห็นในปัญหาที่มีอยู่
พบปัญหาในการติดตั้งใช้งานใช่ไหม
หากพบข้อบกพร่องในการใช้งาน Chrome
รายงานข้อบกพร่องที่ https://new.crbug.com โดยระบุรายละเอียดให้มากที่สุด วิธีการง่ายๆ ในการจำลองข้อบกพร่อง และตั้งค่าคอมโพเนนต์เป็น Blink>ContentIndexing
หากมีแผนจะใช้ API
หากวางแผนที่จะใช้ Content Indexing API ในแอปเว็บ การรองรับแบบสาธารณะของคุณจะช่วย Chrome จัดลําดับความสําคัญของฟีเจอร์ต่างๆ และแสดงให้เห็นว่าการสนับสนุนฟีเจอร์เหล่านี้สำคัญเพียงใดต่อผู้ให้บริการเบราว์เซอร์รายอื่นๆ
- ส่งทวีตถึง @ChromiumDev โดยใช้แฮชแท็ก
#ContentIndexingAPI
พร้อมรายละเอียดเกี่ยวกับตำแหน่งและวิธีใช้
การจัดทําดัชนีเนื้อหาส่งผลต่อความปลอดภัยและความเป็นส่วนตัวอย่างไรบ้าง
ดูคำตอบที่ให้กับแบบสอบถามด้านความปลอดภัยและความเป็นส่วนตัวของ W3C หากมีคำถามเพิ่มเติม โปรดเริ่มการสนทนาผ่าน GitHub repo ของโปรเจ็กต์
รูปภาพหลักโดย Maksym Kaharlytskyi ใน Unsplash