Service Workers

В этой статье я хотел бы поговорить о Service Workers (SW). SW позволяет нам сделать наше приложение готовым к работе в автономном режиме, чтобы оно работало, даже если у нас нет подключения к Интернету. Они также позволяют нам использовать множество других расширенных функций, таких как push-уведомления или фоновая синхронизация. SW продолжает работать даже после закрытия браузера, то есть сервис-воркер продолжает работать. Это фоновый процесс. Итак, давайте зарегистрируем нашего первого сервис-воркера.

(В этой статье я реализую функциональность, связанную с SW, на простом JS, потому что код написан на простом JS, который мы можем интегрировать в любые JS-фреймворки, такие как Angular, React или Vue)

В качестве первого шага давайте добавим файл sw.js в корневую папку вашего проекта. В app.js мы должны проверить, доступен ли сервис-воркер в навигаторе, то есть поддерживается ли сервис-воркер данным браузером. Теперь, когда мы знаем, что сервис-воркеры доступны, мы можем выполнить метод navigator.serviceWorker.register(), чтобы зарегистрировать новый сервис-воркер, указывающий путь к файлу, в котором находится наш сервис-воркер. Этот метод фактически возвращает обещание. Таким образом, чтобы получить информацию, как только это будет сделано, мы можем сцепить их после этого.

Поскольку мы зарегистрировали наш первый сервис-воркер, давайте добавим наш первый прослушиватель событий. Как я уже говорил, ПО работает в фоновом режиме. Но я не упомянул одну вещь, что все они связаны с обработкой событий. Чтобы прикрепить обработчиков событий к сервис-воркеру, мы в первую очередь должны сослаться на него с помощью ключевого слова self, которое в основном означает «дайте мне доступ к сервис-воркеру», а затем мы можем выполнить метод addEventListener(). В сервис-воркере у нас есть доступ к специальному набору событий, например, событию установки, которое будет запущено, когда браузер установит сервис-воркер. Там мы выполняем функцию, мы получаем объект события, который автоматически передается в функцию браузером, и этот объект дает нам информацию о событии установки. Как мы видим, наш сервис-воркер успешно установлен.

Теперь мы можем приступить к реализации статического или предварительного кэширования. Фаза установки сервис-воркера — отличное место для кэширования некоторых активов, которые не меняются очень часто, например оболочки вашего приложения или базового стиля. В обработчике событий установки мы пишем caches, чтобы получить доступ к API кеша, затем метод open() передает имя нашего кеша. Тем самым мы открываем там новый кеш. Но сначала нам нужно обернуть это выражение выражением event.waitUntil(). Он просто ждет, пока вся работа с кэшированием не будет сделана. Это не позволит завершить событие установки. В блоке then мы обращаемся к этому кешу и теперь можем добавить в него контент. Написав cache.addAll(), мы добавляем файлы, которые представляют нашу оболочку приложения.

Теперь давайте посмотрим, действительно ли эти файлы загружены в хранилище кеша. И действительно, они есть.

В качестве следующего шага мы должны извлечь эти файлы из кеша, чтобы наше приложение могло работать в автономном режиме. Давайте посмотрим, как это сделать. Еще одно очень важное событие, которое мы также можем прослушивать, — это событие fetch. Fetch будет запускаться всякий раз, когда наше веб-приложение что-то извлекает, например файлы css и js или даже запросы xhr. Итак, в прослушивателе события fetch сервис-воркера давайте удостоверимся, что мы действительно извлекаем данные из нашего кеша. Сначала я добавлю это решение, а затем объясню, как оно работает.

Выражение event.respondWith() позволяет нам перезаписывать данные, которые возвращаются. Вы можете думать о сервис-воркере как о сетевом прокси, по крайней мере, если мы используем здесь событие fetch. Таким образом, каждый исходящий запрос на выборку проходит через сервис-воркера, как и каждый ответ. То есть, если мы ничего не делаем, ответ просто передается дальше, и мы не получим никакого ответа. Выражение cashes.match() позволяет нам проверить, кэширован ли уже данный запрос. Если это так, он вернет кешированный ответ. Мы не делаем сетевой запрос, мы перехватываем запрос и не выдаем новый, вместо этого мы просто смотрим, что мы хотели запросить, и смотрим, есть ли это в кеше и есть ли оно. есть, мы возвращаем его оттуда. С другой стороны, если мы не находим его в кеше, то мы хотим вернуть запрос на выборку, где мы достигаем или где мы просто продолжаем исходный запрос, поэтому верните fetch(event.request). После всех этих изменений теперь мы наконец-то можем использовать наше веб-приложение в автономном режиме. Воля 🙂

Как видите, наше веб-приложение содержит диаграмму со статическими данными, и ничего не происходит, когда вы нажимаете кнопку «ПОЛУЧИТЬ ДАННЫЕ». Теперь я хочу, чтобы после нажатия этой кнопки мы получали некоторые статистические данные, отображали их на диаграмме и сохраняли эти данные в кеше. Таким образом, мы реализуем динамическое кэширование. Итак, начнем. Допустим, у нас есть конечная точка, которая возвращает статистические данные о том, сколько пользователей посетили наш поддельный сайт. Итак, теперь нам нужно получить эти данные и отобразить их на графике.

Как и прежде, я добавлю решение и объясню, как оно работает.

Динамическое кэширование просто означает, что у нас в любом случае есть событие выборки, и мы хотим сохранить ответ, который возвращается в нашем кеше. Как и прежде, мы пишем кеш, чтобы получить доступ к API кеша и методу open(), передавая имя нашего кеша. Выражение cache.put() просто сохраняет данные, которые у вас есть. Первый аргумент, который вы передаете в put, — это URL-адрес запроса события, идентификатор. Второй аргумент — ответ. Итак, мы сохраняем точный клон, который нам нужен, он содержит все данные ответа, но мы возвращаем исходный ответ. Вот и все. Впервые мы берем данные статистики с нашего сервера и сохраняем их в кэше. Во второй раз мы возьмем эти данные из кеша. Это решение отлично работает не только с запросами xhr. Например, таким образом мы можем динамически кэшировать файлы css или даже изображения.

Фууух, сколько новой информации.

Кстати, и в дополнение хочу сказать несколько слов о фоновой синхронизации. Фоновая синхронизация — это отправка данных на сервер, когда у нас нет подключения к Интернету. Так как же это работает за кулисами? Мы можем использовать сервис-воркер для регистрации задачи синхронизации. Теперь, конечно, регистрация одной задачи — это еще не все, что нам нужно сделать, нам также нужно хранить данные, которые мы хотим отправить с запросом, в индексированной базе данных. Поэтому, если у нас не было подключения и оно было восстановлено, сервисный работник немедленно выполнит эту задачу. Так называемое событие синхронизации будет выполнено на сервис-воркере, и мы сможем прослушать это событие. Круто то, что это будет работать, даже если мы закроем вкладку или на мобильных телефонах даже браузер. Теперь я хочу зарегистрировать первую задачу синхронизации, и для этого я прежде всего проверю, есть ли у нас доступ к сервис-воркерам в данном браузере. Однако мы также должны проверить, доступен ли диспетчер синхронизации в окне. Менеджер синхронизации — это, по сути, API, с помощью которого мы используем функции фоновой синхронизации. Затем я свяжусь со своим сервис-воркером и вызову готовое свойство, чтобы убедиться, что оно настроено. Итак, теперь мы можем работать с сервис-воркером. Чтобы зарегистрировать новую задачу синхронизации, нам нужно получить доступ к свойству синхронизации (это дает нам доступ к диспетчеру синхронизации), и там мы можем вызвать метод регистрации. Он принимает только один аргумент, и это идентификатор, который идентифицирует данную задачу синхронизации. Итак, я дам ему имя «запрос на синхронизацию». Позже мы будем использовать это имя в сервис-воркере, чтобы отреагировать на восстановление подключения и проверить, какие невыполненные задачи у нас есть, а затем мы можем использовать тег, чтобы узнать, что нам нужно сделать с этой задачей.

Теперь я хочу реализовать после нажатия кнопки «POST DATA», мы сохраним данные, которые мы хотим отправить, в indexedDB и зарегистрируем новую задачу синхронизации. Для этого мы прежде всего должны добавить в наш проект несколько дополнительных файлов, чтобы легко работать с индексированной БД. Затем давайте создадим те данные, которые мы хотим сохранить. Это будет простой объект с двумя свойствами. Первым свойством является идентификатор. Второе свойство называется «воскресенье», значение которого равно 10 (для полноты нашей диаграммы :)). Для хранения этих данных мы используем вспомогательную функцию с именем writeData из утилиты.js, которая принимает два аргумента. Первый аргумент — это имя базы данных, в которой будут храниться данные, а второй — сами наши данные. После успешного выполнения мы регистрируем новую задачу синхронизации.

И, наконец, мы добрались до самого интересного — прослушивания события синхронизации и соответствующей реакции на восстановление связи. Как и прежде, я добавлю решение и объясню, как оно работает.

Сначала мы должны проверить тег события. Затем я использую event.waitUntil(), как и раньше, это просто позволяет мне убедиться, что событие не завершится. превентивно. Затем мы получаем данные, которые мы сохранили в indexedDB (используя вспомогательную функцию из утилиты.js), прокручиваем их, отправляем почтовый запрос для каждого из фрагментов данных, которые нужно сохранить, а затем удаляем их из indexedDB, если мы успешно отправили их на сервер. . Это все. Давайте теперь попробуем это. Чтобы проверить эту функциональность, мы должны отключиться в нашем браузере, нажать кнопку «POST DATA», а затем снова подключиться к сети.

После нажатия кнопки «POST DATA», когда мы в автономном режиме, ничего не происходит, но когда подключение восстанавливается, мы видим, что синхронизация была выполнена.

And to confirm that data was really sent to server, we first need to delete our get request from the dynamic cache and click on the “GET DATA” button. Volia 🙂

На этом пока все, ребята. Увидимся позже. Мой код доступен на github:  GitHub – Draakan/simplePWA

Share This

What's your reaction?
0Smile0Lol0Wow0Love0Sad0Angry

Leave a comment