Indeksowanie stron offline za pomocą interfejsu Content Indexing API

Umożliwienie mechanizmom service worker informowania przeglądarkom, które strony działają w trybie offline

Czym jest interfejs Content Crawl API?

Korzystanie z progresywnej aplikacji internetowej oznacza dostęp do informacji, które są ważne dla użytkowników, m.in. obrazów, filmów i artykułów – niezależnie od bieżącego stanu połączenia sieciowego. Technologie takie jak skrypty service worker, Cache Storage API i IndexedDB – zapewniają elementy składowe do przechowywania i udostępniania danych, gdy użytkownicy wchodzą w bezpośrednią interakcję z aplikacją PWA. Stworzenie wysokiej jakości PWA opartej na działaniu w trybie offline to tylko część sukcesu. Jeśli użytkownicy nie zdają sobie sprawy, że treść aplikacji internetowej jest dostępna w trybie offline, nie będą w pełni korzystać z możliwości, jakie trzeba włożyć w jej wdrożenie.

Jest to problem odkrywania. W jaki sposób aplikacja PWA może poinformować użytkowników o treściach dostępnych offline, aby mogli odkryć i obejrzeć dostępne treści? Rozwiązaniem tego problemu jest interfejs Content Crawl API. Dla programistów część tego rozwiązania to rozszerzenie mechanizmów Service Worker, które umożliwiają im dodawanie adresów URL i metadanych stron dostępnych w trybie offline do lokalnego indeksu obsługiwanego przez przeglądarkę. To ulepszenie jest dostępne w Chrome 84 i nowszych wersjach.

Gdy indeks zostanie wypełniony treściami z Twojej aplikacji PWA oraz wszystkich innych zainstalowanych aplikacji PWA, zostanie on wyświetlony przez przeglądarkę w sposób pokazany poniżej.

Zrzut ekranu z elementem menu Pobrane na stronie nowej karty w Chrome.
Najpierw na stronie nowej karty w Chrome wybierz pozycję menu Pobrane.
Multimedia i artykuły dodane do indeksu.
Multimedia i artykuły, które zostały dodane do indeksu, będą widoczne w sekcji Artykuły dla Ciebie.

Dodatkowo Chrome może z wyprzedzeniem rekomendować treści, gdy wykryje, że użytkownik jest offline.

Interfejs Content Crawl API nie jest alternatywnym sposobem umieszczania treści w pamięci podręcznej. To sposób na dostarczanie metadanych stron, które są już zapisane w pamięci podręcznej przez skrypt service worker, dzięki czemu przeglądarka wyświetla te strony, gdy użytkownicy zechcą je wyświetlić. Interfejs Content Crawl API pomaga wykrywalność stron w pamięci podręcznej.

Zobacz, jak to działa

Aby lepiej poznać interfejs Content Crawl API, wypróbuj przykładową aplikację.

  1. Sprawdź, czy korzystasz z obsługiwanej przeglądarki i platformy. Obecnie jest to możliwe tylko w Chrome 84 lub nowszej wersji na urządzeniach z Androidem. Otwórz about://version, aby sprawdzić, jakiej wersji Chrome używasz.
  2. Wejdź na https://contentindex.dev.
  3. Kliknij przycisk + obok co najmniej jednej pozycji na liście.
  4. (Opcjonalnie) Wyłącz na urządzeniu połączenie z siecią Wi-Fi i komórkową transmisję danych lub włącz tryb samolotowy, aby symulować przenoszenie przeglądarki do trybu offline.
  5. Z menu Chrome wybierz Pobrane i otwórz kartę Artykuły dla Ciebie.
  6. Przejrzyj zapisane wcześniej treści.

Źródło przykładowej aplikacji możesz wyświetlić na GitHubie.

Inna przykładowa aplikacja, PWA w notatniku, przedstawia wykorzystanie interfejsu Content Crawl API w połączeniu z interfejsem Web Share Target API. Kod pokazuje technikę synchronizowania interfejsu Content Crawl API z elementami przechowywanymi przez aplikację internetową za pomocą Cache Storage API.

Korzystanie z interfejsu API

Aby można było korzystać z interfejsu API, Twoja aplikacja musi mieć skrypt service worker i adresy URL, z których można nawigować offline. Jeśli Twoja aplikacja internetowa nie ma obecnie skryptu service worker, biblioteki Workspace mogą ułatwić jego utworzenie.

Jakiego typu adresy URL mogą być indeksowane w trybie offline?

Interfejs API obsługuje adresy URL indeksowania odpowiadające dokumentom HTML. Na przykład adresu URL pliku multimedialnego z pamięci podręcznej nie można zindeksować bezpośrednio. Zamiast tego podaj adres URL strony, która wyświetla multimedia i działa offline.

Zalecanym wzorcem jest utworzenie „strony HTML wyświetlającej”, która mogłaby zaakceptować adres URL źródła jako parametr zapytania, a następnie wyświetlać zawartość pliku, potencjalnie z dodatkowymi elementami sterującymi lub treścią na stronie.

Aplikacje internetowe mogą dodawać do indeksu treści tylko adresy URL, które należą do zakresu bieżącego skryptu service worker. Innymi słowy, aplikacja internetowa nie może dodać do indeksu treści adresu URL należącego do zupełnie innej domeny.

Przegląd

Interfejs Content Crawl API obsługuje 3 operacje: dodawanie, wyświetlanie i usuwanie metadanych. Te metody są dostępne w nowej usłudze index, która została dodana do interfejsu ServiceWorkerRegistration.

Pierwszym krokiem w indeksowaniu treści jest uzyskanie odniesienia do bieżącej strony ServiceWorkerRegistration. navigator.serviceWorker.ready to najprostszy sposób:

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!
}

Jeśli wywołujesz interfejs Content Crawl API z poziomu skryptu service worker, a nie na stronie internetowej, możesz odwoływać się do ServiceWorkerRegistration bezpośrednio za pomocą registration. Będzie ona już definiowana jako część ServiceWorkerGlobalScope.

Dodawanie do indeksu

Do indeksowania adresów URL i powiązanych z nimi metadanych używaj metody add(). To Ty decydujesz, kiedy elementy mają być dodawane do indeksu. Możesz dodawać go do indeksu w odpowiedzi na wprowadzone dane, np. kliknięcie przycisku „Zapisz offline”. Możesz też dodawać elementy automatycznie po każdej aktualizacji danych w pamięci podręcznej. Służy do tego mechanizm, np. okresowa synchronizacja w tle.

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',
});

Dodanie wpisu ma wpływ tylko na indeks treści i nie wnosi nic do pamięci podręcznej.

Eliminacja brzegowa: wywołaj funkcję add() z kontekstu window, jeśli ikony korzystają z modułu obsługi fetch

Gdy wywołujesz add(), Chrome żąda adresu URL każdej ikony, by upewnić się, że udostępni ona kopię ikony, która ma być używana do wyświetlenia listy zindeksowanych treści.

  • Jeśli wywołujesz add() z kontekstu window (czyli z Twojej strony internetowej), spowoduje to wywołanie zdarzenia fetch w skrypcie service worker.

  • Jeśli wywołasz add() w skrypcie service worker (np. w innym module obsługi zdarzeń), żądanie nie wywoła modułu obsługi fetch tego skryptu. Ikony będą pobierane bezpośrednio, bez udziału skryptu service worker. Pamiętaj o tym, jeśli ikony zależą od modułu obsługi fetch, np. dlatego, że istnieją tylko w lokalnej pamięci podręcznej, a nie w sieci. Jeśli tak, pamiętaj, by wywoływać funkcję add() tylko z kontekstu window.

Wyświetlanie zawartości indeksu

Metoda getAll() zwraca obietnicę utworzenia iteracyjnej listy zindeksowanych wpisów i ich metadanych. Zwrócone wpisy będą zawierać wszystkie dane zapisane w add().

const entries = await registration.index.getAll();
for (const entry of entries) {
  // entry.id, entry.launchUrl, etc. are all exposed.
}

Usuwam elementy z indeksu

Aby usunąć element z indeksu, wywołaj delete(), podając właściwość id elementu:

await registration.index.delete('article-123');

Wywołanie delete() wpływa tylko na indeks. Nie spowoduje to usunięcia niczego z pamięci podręcznej.

Obsługa zdarzenia usunięcia użytkownika

Po wyświetleniu zindeksowanej zawartości przeglądarka może zawierać własny interfejs użytkownika z elementem menu Usuń, dzięki czemu użytkownicy mogą wskazać, że zakończyli wyświetlanie wcześniej zindeksowanej zawartości. Tak wygląda interfejs usuwania w Chrome 80:

Pozycja menu usuwania.

Gdy ktoś wybierze tę pozycję z menu, skrypt service worker aplikacji internetowej otrzyma zdarzenie contentdelete. Chociaż obsługa tego zdarzenia jest opcjonalna, umożliwia mechanizmowi service worker „wyczyścić” treści, takie jak pliki multimedialne przechowywane w pamięci lokalnej, które ktoś uznał za skończone.

Nie musisz wywoływać funkcji registration.index.delete() w module obsługi contentdelete. Jeśli zdarzenie zostało wywołane, przeglądarka już usunęła odpowiedni indeks.

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.
});

Opinia na temat projektu interfejsu API

Czy interfejs API jest nietypowy lub nie działa zgodnie z oczekiwaniami? A może brakuje w nich elementów, które są niezbędne do realizacji pomysłu?

Zgłoś problem w repozytorium GitHub z objaśnieniem interfejsu Content Crawl API lub dodaj swoje uwagi do istniejącego problemu.

Problem z implementacją?

Czy wystąpił błąd związany z implementacją przeglądarki Chrome?

Zgłoś błąd na https://new.crbug.com. Podaj jak najwięcej szczegółów, proste instrukcje odtwarzania i ustaw wartość Blink>ContentIndexing w sekcji Komponenty.

Planujesz korzystać z interfejsu API?

Planujesz używać interfejsu Content Crawl API w swojej aplikacji internetowej? Twoje publiczne wsparcie pomaga Chrome nadawać priorytet funkcjom i pokazać innym dostawcom przeglądarek, jak ważne jest ich wsparcie.

Jakie skutki dla bezpieczeństwa i ochrony prywatności wiąże się z indeksowaniem treści?

Zapoznaj się z odpowiedziami udzielonymi przez W3C w kwestionariuszu W3C dotyczącym bezpieczeństwa i prywatności. Jeśli masz więcej pytań, rozpocznij dyskusję w repozytorium GitHub projektu.

Baner powitalny autorstwa Maksyma Kaharlytskyi w filmie Unsplash.