การช่วยให้ 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 ไม่ใช่วิธีอื่นในการแคชเนื้อหา ซึ่งเป็นวิธีให้ข้อมูลเมตาเกี่ยวกับหน้าเว็บที่พนักงานบริการของคุณมีแคชไว้อยู่แล้ว เพื่อให้เบราว์เซอร์สามารถแสดงหน้าเหล่านั้นได้เมื่อผู้ใช้มีแนวโน้มที่จะต้องการดูหน้าเหล่านั้น 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 จะช่วยให้การสร้างไฟล์ทำได้ง่ายขึ้น
URL ประเภทใดบ้างที่จัดทําดัชนีได้ว่าเป็น URL ที่ใช้งานได้แบบออฟไลน์
API รองรับการจัดทําดัชนี URL ที่สอดคล้องกับเอกสาร HTML ตัวอย่างเช่น URL ของไฟล์สื่อที่แคชไว้จะจัดทำดัชนีโดยตรงไม่ได้ แต่คุณต้องระบุ URL ของหน้าเว็บที่แสดงสื่อและใช้งานได้แบบออฟไลน์แทน
รูปแบบที่แนะนำคือสร้างหน้า HTML "โปรแกรมดู" ที่ยอมรับ 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 เข้ามาเกี่ยวข้อง โปรดคำนึงถึงเรื่องนี้หากไอคอนใช้ตัวแฮนเดิล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 ของโปรเจ็กต์
รูปภาพหลักโดย Maksym Kaharlytskyi ใน Unsplash