Indeksowanie stron offline za pomocą interfejsu Content Indexing API

Włączanie obsługi przez service workera, aby informować przeglądarki, które strony działają offline

Czym jest interfejs Content Indexing API?

Korzystanie z progresywnej aplikacji internetowej oznacza dostęp do informacji, na których zależy użytkownikom – obrazów, filmów, artykułów i innych treści, niezależnie od obecnego stanu połączenia sieciowego. Technologie takie jak elementy usługi, interfejs Cache Storage APIIndexedDB stanowią elementy składowe umożliwiające przechowywanie i przekazywanie danych, gdy użytkownicy bezpośrednio wchodzą w interakcję z PWA. Jednak tworzenie wysokiej jakości PWA z możliwością korzystania offline to tylko część rozwiązania. Jeśli użytkownicy nie będą wiedzieć, że treści aplikacji internetowej są dostępne w trybie offline, nie wykorzystają w pełni pracy, jaką włożysz w wdrożenie tej funkcji.

To problem wykrywalności: jak Twoja PWA może poinformować użytkowników o dostępnych treściach offline, aby mogli je odkryć i zobaczyć? Rozwiązaniem tego problemu jest Content Indexing API. Część tego rozwiązania przeznaczona dla deweloperów to rozszerzenie dla usług działających w tle, które umożliwia deweloperom dodawanie adresów URL i metadanych stron obsługujących tryb offline do indeksu lokalnego zarządzanego przez przeglądarkę. Jest ono dostępne w Chrome 84 i nowszych wersjach.

Gdy indeks zostanie uzupełniony zawartością Twojej aplikacji PWA, a także innymi zainstalowanymi aplikacjami PWA, wyświetli się ona w przeglądarce w sposób pokazany poniżej.

Zrzut ekranu przedstawiający pozycję menu Pobrane na stronie nowej karty w Chrome.
Na stronie nowej karty w Chrome wybierz menu Pobrane.
Multimedia i artykuły dodane do indeksu.
Treści multimedialne i artykuły dodane do indeksu będą wyświetlane w sekcji Artykuły dla Ciebie.

Dodatkowo Chrome może aktywnie polecać treści, gdy wykryje, że użytkownik jest offline.

Interfejs Content Indexing API nie jest alternatywnym sposobem na buforowanie treści. Jest to sposób na udostępnianie metadanych stron, które są już zapisane w pamięci podręcznej przez usługę, aby przeglądarka mogła wyświetlić te strony, gdy użytkownicy zechcą je zobaczyć. Interfejs Content Indexing API pomaga w wykrywalności stron z pamięci podręcznej.

Zobacz, jak to działa

Najlepszym sposobem na zapoznanie się z interfejsem Content Indexing API jest wypróbowanie przykładowej aplikacji.

  1. Sprawdź, czy korzystasz z obsługiwanej przeglądarki i obsługiwanej platformy. Obecnie ta funkcja jest ograniczona do Chrome 84 lub nowszej wersji na Androida. Otwórz about://version, aby sprawdzić, której wersji Chrome używasz.
  2. Otwórz stronę https://contentindex.dev.
  3. Kliknij przycisk + obok co najmniej jednego elementu na liście.
  4. (Opcjonalnie) Wyłącz połączenie z Wi-Fi i komórkową transmisję danych na urządzeniu lub włącz tryb samolotowy, aby symulować pracę przeglądarki w trybie offline.
  5. W menu Chrome wybierz Pobrania i otwórz kartę Artykuły dla Ciebie.
  6. Przeglądaj wcześniej zapisane treści.

Kod źródłowy przykładowej aplikacji znajdziesz na GitHubie.

Kolejna przykładowa aplikacja, scrapbook PWA, pokazuje wykorzystanie interfejsu Content Indexing API z interfejsem Web Share Target API. Kod pokazuje technikę, która umożliwia utrzymywanie synchronizacji interfejsu Content Indexing API z elementami przechowywanymi przez aplikację internetową za pomocą interfejsu Cache Storage API.

Korzystanie z interfejsu API

Aby korzystać z interfejsu API, aplikacja musi mieć usługę workera i adresy URL, które można przeglądać w trybie offline. Jeśli Twoja aplikacja internetowa nie ma obecnie serwisu workera, biblioteki Workbox mogą ułatwić jego utworzenie.

Jakie adresy URL mogą być indeksowane jako dostępne offline?

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

Zalecanym wzorcem jest utworzenie strony HTML „przeglądającego”, która mogłaby zaakceptować bazowy adres URL multimediów jako parametr zapytania, a następnie wyświetlić zawartość pliku, potencjalnie wraz z dodatkowymi elementami sterującymi lub zawartością strony.

Aplikacje internetowe mogą dodawać do indeksu treści tylko adresy URL, które znajdują się w zakresie bieżącego pracownika obsługi. Innymi słowy, aplikacja internetowa nie może dodać do indeksu treści adresu URL należącego do zupełnie innej domeny.

Omówienie

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

Pierwszym krokiem w indeksowaniu treści jest uzyskanie odwołania do bieżącego elementu ServiceWorkerRegistration. Najprostszym sposobem jest użycie atrybutu 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!
}

Jeśli wywołujesz interfejs Content Indexing API z serwisowego workera, a nie z poziomu strony internetowej, możesz bezpośrednio odwoływać się do ServiceWorkerRegistration za pomocą registration. Już jest zdefiniowany w ramach ServiceWorkerGlobalScope.

Dodawanie do indeksu

Użyj metody add(), aby zindeksować adresy URL i powiązane z nimi metadane. Ty decydujesz, kiedy elementy mają być dodawane do indeksu. Możesz dodać do indeksu dane w odpowiedzi na dane wejściowe, np. kliknięcie przycisku „Zapisz offline”. Możesz też dodawać elementy automatycznie za każdym razem, gdy dane w pamięci podręcznej zostaną zaktualizowane za pomocą mechanizmu takiego jak 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 wpływa tylko na indeks treści i nie dodaje niczego do pamięci podręcznej.

Wyjątek: wywołaj add() z kontekstu window, jeśli ikony korzystają z obsługi fetch

Gdy wywołasz funkcję add(), Chrome wysyła żądanie dotyczące adresu URL każdej ikony, aby mieć kopię ikony do użycia podczas wyświetlania listy zindeksowanych treści.

  • Jeśli wywołasz add() z kontekstu window (czyli z Twojej strony internetowej), to żądanie spowoduje wywołanie zdarzenia fetch w Twoim serwisie.

  • Jeśli wywołasz funkcję add() w skrypcie service worker (np. w ramach innego przetwarzacza zdarzeń), to żądanie nie nie spowoduje wywołania przetwarzacza fetch skryptu service worker. Ikony będą pobierane bezpośrednio, bez udziału skryptu usługi. Pamiętaj o tym, jeśli ikony są zależne od modułu fetch, być może dlatego, że istnieją tylko w lokalnym pamięci podręcznej, a nie w sieci. Jeśli tak, zadzwoń do add() tylko z kontekstu window.

Wykaz zawartości indeksu

Metoda getAll() zwraca obietnicę dotyczącą przekształcalnej listy zindeksowanych wpisów i ich metadanych. Zwrócone wpisy będą zawierać wszystkie dane zapisane za pomocą typu add().

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

Usuwanie elementów z indeksu

Aby usunąć element z indeksu, wywołaj funkcję delete(), podając id elementu, który ma zostać usunięty:

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

Wywołanie funkcji delete() ma wpływ tylko na indeks. Nie usuwa niczego z pamięci podręcznej.

Obsługa zdarzenia usunięcia użytkownika

Gdy przeglądarka wyświetla zindeksowane treści, może zawierać własny interfejs z opcją Usuń, która umożliwia użytkownikom wskazanie, że skończyli przeglądanie wcześniej zindeksowanych treści. Tak wygląda interfejs usuwania w Chrome 80:

Usuń pozycję menu.

Gdy ktoś wybierze ten element menu, worker usługi Twojej aplikacji internetowej otrzyma zdarzenie contentdelete. Obsługa tego zdarzenia jest opcjonalna, ale daje możliwość „posprzątania” treści, takich jak pliki multimedialne w miejscowym pamięci podręcznej, które ktoś oznaczył jako niepotrzebne.

Nie musisz wywoływać funkcji registration.index.delete() w obiekcie contentdelete. Jeśli zdarzenie zostało wywołane, przeglądarka już wykonała usunięcie odpowiedniego indeksu.

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

Opinie na temat projektu interfejsu API

Czy interfejs API jest niewygodny lub nie działa zgodnie z oczekiwaniami? A może brakuje Ci elementów, których potrzebujesz, aby zrealizować swój pomysł?

Zgłoś problem w repozytorium GitHub tłumaczenia interfejsu Content Indexing API lub podziel się swoją opinią na temat istniejącego problemu.

Problem z implementacją?

Czy znalazłeś/znalazłaś błąd w implementacji Chrome?

Prześlij zgłoszenie błędu na stronie https://new.crbug.com. Podaj jak najwięcej szczegółów, proste instrukcje odtwarzania błędu i ustaw wartość Components na Blink>ContentIndexing.

Planujesz korzystać z interfejsu API?

Planujesz użyć interfejsu Content Indexing API w aplikacji internetowej? Twoje publiczne wsparcie pomaga Chrome ustalać priorytety funkcji i pokazuje innym dostawcom przeglądarek, jak ważne jest ich wsparcie.

Jakie są konsekwencje indeksowania treści dla bezpieczeństwa i prywatności?

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

Baner powitalny autorstwa Maksym Kaharlytskyi z Unsplash.