การเปิดใช้ 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 แสดงการใช้ 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 ใดๆ เข้ามาเกี่ยวข้อง โปรดคำนึงถึงเรื่องนี้หากไอคอนใช้ตัวแฮนเดิล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 ก็มีโอกาสของ 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 โดยระบุรายละเอียดให้มากที่สุดเท่าที่จะทำได้ วิธีการง่ายๆ ในการสร้างซ้ำ และตั้งค่า Components เป็น Blink>ContentIndexing
หากมีแผนจะใช้ API
หากวางแผนที่จะใช้ Content Indexing API ในแอปเว็บ การสนับสนุนสาธารณะของคุณช่วยให้ Chrome จัดลำดับความสำคัญของฟีเจอร์ต่างๆ และแสดงให้ผู้ให้บริการเบราว์เซอร์รายอื่นเห็นว่าการสนับสนุนฟีเจอร์เหล่านี้นั้นสำคัญเพียงใด
- ส่งทวีตถึง @ChromiumDev โดยใช้แฮชแท็ก
#ContentIndexingAPI
พร้อมรายละเอียดเกี่ยวกับตำแหน่งและวิธีใช้
ผลกระทบของการจัดทำดัชนีเนื้อหาที่มีต่อความปลอดภัยและความเป็นส่วนตัวมีอะไรบ้าง
ดูคำตอบที่ให้กับแบบสอบถามด้านความปลอดภัยและความเป็นส่วนตัวของ W3C หากมีคำถามเพิ่มเติม โปรดเริ่มการสนทนาผ่าน GitHub repo ของโปรเจ็กต์
รูปภาพหลักโดย Maksym Kaharlytskyi ใน Unsplash