Всем привет! Это мой первый пост на Medium. Он охватывает настройку и расширение встроенного сервис-воркера в приложении React, созданном с использованием шаблона CRA.

Что такое сервис-воркер?

Service worker - это сценарий, который выполняется в фоновом потоке и действует как сетевой прокси для веб-приложения. Он имеет такие возможности, как перехват всех сетевых запросов в указанной области, кэширование файлов, фоновая синхронизация, push-уведомление и т. Д., Что делает его очень полезным для добавления автономной поддержки на сайт или создания PWA (прогрессивного веб-приложения).

Пожалуйста, проверьте эту ссылку, чтобы получить дополнительную информацию об основах работы в Интернете.

На заметку:

  • Service worker - это сценарий, который выполняется в независимом потоке браузера (не блокируя основной поток). Следовательно, он может работать в фоновом режиме даже при отсутствии веб-страницы.
  • Он не может получить прямой доступ к DOM. Ссылается на происхождение.
  • Веб-приложение должно работать на HTTPS или localhost.
  • Сервисный работник может получить доступ к indexedDB, кешу.
  • Он может только перехватывать запросы от клиентов, сделанные в его рамках. Максимальный объем работника службы - это его местонахождение в корне сервера. Например,
Case-A
/root
  /service-worker.js
  ...
Case-B
/root
  /home
    /service-worker.js
    ...
  /about
  ...

В случае-A сервис-воркер может перехватывать каждый запрос, сделанный, в то время как в случае-B он может перехватывать только запросы, сделанные из сценариев в /home.

ПРИМЕЧАНИЕ. В этом посте я собираюсь использовать Workbox для создания сервис-воркера. Workbox - это SDK, который берет на себя большую часть стандартного кода при создании конфигурации сервис-воркера.

Эта проблема

Thecreate-react-app действительно предоставляет сервис-воркера прямо из коробки, но только с ограниченными возможностями, то есть с предварительным кэшированием ресурсов в /build/static. Вы можете найти ряд запросов на вытягивание, которые все еще находятся в открытом / проверяемом состоянии в общедоступном репозитории CRA, чтобы улучшить встроенного сервис-воркера.

В этом посте будет описан обходной путь для расширения возможностей встроенного ПО и получения большего контроля.

А теперь без лишних слов, приступим!

Перво-наперво!

  • Пусть реализация CRA позаботится о регистрации и обновлении сервис-воркеров (в основном шаблонные и тяжелые). Мы возьмем на себя управление установкой и добавим бизнес-логику.
  • Мы используем Workbox в качестве инструмента сборки сервис-воркера. Следовательно, создайте следующие файлы без содержимого и заполните их в / src как,
  1. src / sw-build.js → Для предоставления инструкций по созданию настроенного сервис-воркера.
  2. src / sw-custom.js → Чтобы добавить наши собственные правила

Создание сценария сборки SW

Поскольку наши файлы генерируются динамически с использованием react-scripts, нам нужен способ узнать имена файлов для их предварительного кэширования. В Workbox есть встроенный метод injectManifest, который позаботится об этом. Вам нужно только указать шаблоны файлов, которые необходимо просканировать, и место назначения, в котором они должны быть упомянуты для предварительного кеширования. "Вы можете прочитать больше об этом здесь".

Добавьте следующий фрагмент кода в src / sw-build.js,

swSrc: Путь к нашим правилам пользовательского сервис-воркера

swDest: Целевой путь, по которому создается последний файл сервис-воркера.

globDirectory: Каталог для поиска файлов, требующих проповеди

globPatterns: сопоставить файлы, соответствующие этому регулярному выражению

maximumFileSizeToCacheInBytes: Как следует из названия, мы кэшируем все файлы размером менее 5 МБ.

В приведенном выше сценарии мы указали рабочую область для поиска шаблонов файлов, указанных в globPatterns, и записи их в swSrc.

Теперь эта функция ищет следующий заполнитель в swSrc для записи сгенерированных имен файлов,

workbox.precaching.precacheAndRoute([]);

Добавление собственных правил для нашего сервис-воркера

  1. Чтобы работать с библиотеками сервис-воркеров рабочих ящиков, давайте инициализируем глобальный рабочий ящик.
  2. Пожалуйста, обратитесь к этой документации для использования методов библиотеки workbox-sw. Приведенный ниже фрагмент кода включает образцы правил кеширования для разных типов файлов.

Теперь обновите содержимое вашего src / sw-custom.js этим.

Объяснение

  1. importScripts является частью WorkerGlobalScope Web API, который загружает запрошенный файл javascript, в нашем случае рабочий ящик.
  2. Когда глобальный рабочий ящик готов к использованию, пользовательские конфигурации можно добавить с помощью workbox.setConfig, например, переключать журналы отладки в зависимости от среды.
  3. self - это переменная только для чтения и часть WorkBoxGlobalScope Web API, которая может относиться как к глобальной, так и к любой конкретной области (DedicatedWorkerGlobalScope, ServiceWorkerGlobalScope и т. д.)
  4. Остальная часть кода полностью понятна комментариями. Если нет, я бы с удовольствием обсудил их в комментариях :)

Заменить существующее ПО

Я использую [email protected] для создания приложения React с поддержкой машинописного текста.

  1. Как только приложение будет создано, откройте src/serviceWorker.ts.
  2. Вы увидите именованный метод экспорта register. Он содержит прослушиватель событий загрузки окна, откуда загружаются шаги регистрации. Здесь указывается URL-адрес сервис-воркера по умолчанию. Заменим его своим!
export function register(config?: Config) {
  if(
    process.env.NODE_ENV === "production" &&
    "serviceWorker" in navigator
  ) {
      
     ...
     
     window.addEventListener("load", () => {
      // BEFORE
      const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
      // AFTER
      const swUrl = `${process.env.PUBLIC_URL}/sw.js`;
      
      ...

4. Теперь измените serviceWorker.unregister() на serviceWorker.register() под src/index.tsx.

Вот и все! Теперь служебный воркер будет загружен из нашего настраиваемого scriptbuild/sw.js.

Только для машинописного текста

Поскольку мы создали сценарий SW на JS, вы можете исключить его из проверок компилятора TS (чтобы избежать ненужных предупреждений и ошибок). Ниже приведен пример конфигурации в tsconfig.json для исключения сценариев SW,

{
...
 
  "include": ["src"],
 
  "exclude": ["src/sw*", ...]
}

Построить шаги

Я предполагаю, что сборки выполняются в среде Node / Linux. Мы собираемся добавить еще 2 доступных скрипта:

  1. build-sw - Для создания пользовательского сервис-воркера
  2. clean-cra-sw - Для очистки существующего сервис-воркера CRA

Давайте запустим эти команды после build. Теперь updatedpackage.json должен выглядеть так:

"scripts": {
  
  ...
  
  "build-sw": "node ./src/sw-build.js",
  "clean-cra-sw": "rm -f build/precache-manifest.*.js && rm -f build/service-worker.js",
  "build": "react-scripts build && npm run build-sw && npm run clean-cra-sw",
  ...
}

Обработка обновлений [важно]

Service worker считается новым, даже если один байт в sw.js файле был изменен. Следовательно, он снова подвергается методам жизненного цикла сервис-воркеров. Это означает, что новый сервис-воркер должен быть установлен (проповедуя файлы), а затем активирован (после обновления кеша новыми файлами).

Теперь в идеале сервис-воркер ожидает активации после того, как все открытые вкладки для нашего сайта будут закрыты. Тем не менее, мы использовали self.skipWaiting() в наших пользовательских правилах, что заставляет нашего рабочего перейти в activated состояние. Таким образом, только перезагрузка текущей вкладки должна быть достаточной, чтобы новые изменения стали доступными.

Следовательно, пользователь должен получить запрос на перезагрузку страницы, когда доступно обновление, чтобы всегда видеть последние изменения. Событие обновления по своей сути инициируется нашим стандартным кодом сервис-воркера. Таким образом, вам просто нужно предоставить объект, содержащий обработчик обновлений, в качестве аргумента для метода регистрации сервис-воркера.

Например, в файле src / index.tsx обновите регистрационный вызов с помощью

const updateHandler = (registration: ServiceWorkerRegistration) => {
    if (window.confirm("Update available. Do you want to reload?")){
      window.location.reload();
    }
};
serviceWorker.register({
  onUpdate: updateHandler,
});

Это все. Теперь создайте и запустите приложение и откройте браузер, чтобы проверить работника службы в действии. В Chrome вы можете проверить это, проверив вкладку «Приложение», например,

В LoginRadius использование сервис-воркера сэкономило нам почти 60% времени загрузки при последующих загрузках, что помогло нам достичь более 80% удовлетворенности пользователей по сравнению с предыдущими 55 %.

P.S этот пост был вдохновлен проблемой использования GitHub в Workbox. Также ознакомьтесь с этой ссылкой на YouTube, чтобы узнать о PWA в действии.

Спасибо, что прочитали это, и дайте мне знать ваше мнение в комментариях :)