Индексирование страниц с возможностью автономной работы с помощью Content Indexing API

Предоставление сервисным работникам возможности сообщать браузерам, какие страницы работают в автономном режиме.

Что такое API индексирования контента?

Использование прогрессивного веб-приложения (PWA) означает доступ к информации, которая важна для пользователей — изображениям, видео, статьям и многому другому — независимо от текущего состояния вашего сетевого соединения. Такие технологии, как сервис-воркеры , API кэширования и IndexedDB, предоставляют вам необходимые инструменты для хранения и предоставления данных при непосредственном взаимодействии пользователей с PWA. Но создание высококачественного PWA, ориентированного на работу в автономном режиме, — это лишь часть дела. Если пользователи не понимают, что контент веб-приложения доступен в автономном режиме, они не смогут в полной мере воспользоваться результатами вашей работы по реализации этой функциональности.

Это проблема обнаружения : как ваше PWA может сообщить пользователям о контенте, доступном в автономном режиме, чтобы они могли найти и просмотреть то, что доступно? API индексирования контента — это решение этой проблемы. Часть решения, предназначенная для разработчиков, представляет собой расширение для сервисных воркеров, которое позволяет разработчикам добавлять URL-адреса и метаданные страниц, доступных в автономном режиме, в локальный индекс, поддерживаемый браузером. Это улучшение доступно в Chrome 84 и более поздних версиях.

После того как индекс будет заполнен контентом из вашего PWA, а также любых других установленных PWA, он будет отображаться в браузере следующим образом.

Пункт меню «Загрузки» на странице новой вкладки Chrome.
Сначала выберите пункт меню «Загрузки» на странице новой вкладки Chrome.
В индекс были добавлены медиафайлы и статьи.
В разделе «Статьи для вас» будут отображаться медиафайлы и статьи, добавленные в указатель.

Кроме того, Chrome может заблаговременно рекомендовать контент, когда обнаружит, что пользователь находится в автономном режиме.

API индексирования контента не является альтернативным способом кэширования контента . Это способ предоставления метаданных о страницах, которые уже кэшированы вашим сервис-воркером, чтобы браузер мог отображать эти страницы, когда пользователи, скорее всего, захотят их просмотреть. API индексирования контента помогает повысить доступность кэшированных страниц.

Посмотрите, как это работает.

Лучший способ ознакомиться с API индексирования контента — попробовать запустить тестовое приложение.

  1. Убедитесь, что вы используете поддерживаемый браузер и платформу. Это относится только к Chrome 84 или более поздней версии для Android . Перейдите по about://version , чтобы узнать, какую версию Chrome вы используете.
  2. Посетите https://contentindex.dev
  3. Нажмите кнопку + рядом с одним или несколькими пунктами в списке.
  4. (Необязательно) Отключите Wi-Fi и мобильную передачу данных на вашем устройстве или включите режим полета, чтобы имитировать отключение браузера от сети.
  5. В меню Chrome выберите «Загрузки» и перейдите на вкладку «Статьи для вас» .
  6. Просмотрите ранее сохраненный контент.

Исходный код примера приложения можно посмотреть на GitHub .

Еще один пример приложения, PWA-приложение для создания альбомов , демонстрирует использование API индексирования контента с API целевого веб-доступа . Код показывает метод синхронизации API индексирования контента с элементами, хранящимися в веб-приложении с помощью API кэширования .

Использование API

Для использования API ваше приложение должно иметь сервис-воркер и URL-адреса, доступные в автономном режиме. Если ваше веб-приложение не имеет сервис-воркера, библиотеки Workbox могут упростить его создание.

Какие типы URL-адресов могут быть проиндексированы как доступные для индексации в автономном режиме?

API поддерживает индексирование URL-адресов, соответствующих HTML-документам. Например, URL-адрес кэшированного медиафайла не может быть проиндексирован напрямую. Вместо этого необходимо указать URL-адрес страницы, отображающей медиафайлы и работающей в автономном режиме.

Рекомендуемый подход заключается в создании HTML-страницы-«просмотрщика», которая могла бы принимать URL-адрес медиафайла в качестве параметра запроса и отображать содержимое файла, возможно, с дополнительными элементами управления или контентом на странице.

Веб-приложения могут добавлять в индекс контента только те URL-адреса, которые находятся в области действия текущего сервис-воркера. Другими словами, веб-приложение не может добавить в индекс контента URL-адрес, принадлежащий совершенно другому домену.

Обзор

API индексирования контента поддерживает три операции: добавление, отображение и удаление метаданных. Эти методы доступны через новое свойство 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!
}

Если вы обращаетесь к API индексирования контента из сервис-воркера, а не из веб-страницы, вы можете напрямую ссылаться на 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:
  // 'homepage', 'article', 'video', 'audio', or '' (default).
  category: 'article',
});

Добавление записи влияет только на индекс контента; оно ничего не добавляет в кэш .

Крайний случай: вызовите метод add() из контекста window , если ваши значки зависят от обработчика fetch handler).

При вызове метода add() Chrome отправит запрос на получение URL-адреса каждого значка, чтобы убедиться, что у него есть копия значка для использования при отображении списка проиндексированного контента.

  • Если вы вызываете метод add() из контекста window (то есть с вашей веб-страницы), этот запрос вызовет событие fetch в вашем сервис-воркере.

  • Если вы вызываете add() внутри вашего сервис-воркера (возможно, внутри другого обработчика событий), запрос не вызовет обработчик fetch сервис-воркера. Иконки будут загружены напрямую, без участия сервис-воркера. Имейте это в виду, если ваши иконки зависят от обработчика 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 . Хотя обработка этого события необязательна, она дает вашему сервис-воркеру возможность «очистить» контент, например, локально кэшированные медиафайлы, с которыми пользователь завершил работу.

Нет необходимости вызывать 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 с описанием API индексирования контента или добавьте свои мысли к уже существующей заявке.

Проблема с реализацией?

Вы обнаружили ошибку в реализации Chrome?

Сообщите об ошибке на https://new.crbug.com . Укажите как можно больше подробностей, инструкции по воспроизведению и установите для параметра Components значение Blink>ContentIndexing .

Планируете использовать API?

Планируете использовать API индексирования контента в своем веб-приложении? Ваша публичная поддержка помогает Chrome расставлять приоритеты в разработке новых функций и показывает другим производителям браузеров, насколько важно их поддерживать.

  • Отправьте твит @ChromiumDev , используя хэштег #ContentIndexingAPI и подробно описав, где и как вы его используете.

Какие последствия для безопасности и конфиденциальности влечет за собой индексирование контента?

Ознакомьтесь с ответами на анкету W3C по вопросам безопасности и конфиденциальности . Если у вас возникнут дополнительные вопросы, начните обсуждение в репозитории проекта на GitHub .