/third-task

Вступительное задание №3

Primary LanguageJavaScript

Задание 3

Мобилизация.Гифки – сервис для поиска гифок в перерывах между занятиями.

Сервис написан с использованием bem-components.

Работа избранного в оффлайне реализована с помощью технологии Service Worker.

Для поиска изображений используется API сервиса Giphy.

В браузерах, не поддерживающих сервис-воркеры, приложение так же должно корректно работать, за исключением возможности работы в оффлайне.

Структура проекта

  • gifs.html – точка входа
  • assets – статические файлы проекта
  • vendor – статические файлы внешних библиотек
  • service-worker.js – скрипт сервис-воркера

Открывать gifs.html нужно с помощью локального веб-сервера – не как файл. Это можно сделать с помощью встроенного в WebStorm/Idea веб-сервера, с помощью простого сервера из состава PHP или Python. Можно воспользоваться и любым другим способом.

Найденные проблемы и их исправление

Автор - Михаил Кононенко

  1. Из-за того, что файл service-worker.js переместили в папку assets, по-видимому, на этапе "разложить файлы красиво", Service Worker перестал обрабатывать запросы из-за изменения его области видимости. Проблема устраняется переносом файла в корень проекта. Ну и сменой пути к нему в файле blocks.js.
  2. Статические файлы из папок vendor и assets семантически не должны обновляться, если в константе написана та же версия, что и при последнем её кэшировании (название кэш-хранилища соответствует названию версии). Само по себе это вовсе не проблема, но раз нужно перекэшировать - нужно поменять константу CACHE_VERSION на любое другое значение.
  3. На этапе fetch в кэше не искалась страница gifs.html (в функции needStoreForOffline), поэтому она вытаскивалась всегда только с сервера. Устранено добавлением поиска этого файла в needStoreForOffline.
  4. Теперь же у нас выявилась и другая проблема, описанная в задании: страница gifs.html стала всегда грузиться из кэша. Это происходит на том же этапе fetch (43 и 44 строка):
response = caches.match(cacheKey)
.then(cacheResponse => cacheResponse || fetchAndPutToCache(cacheKey, event.request));

Эти строки возвращают из кэша файлы всегда, за исключением случая, если в кэше файлов попросту нет. Заменим это на вот это:

response = fetchAndPutToCache(cacheKey, event.request);

Теперь у нас все файлы сначала скачиваются, а только потом, в случае неудачи ищутся в кэше.

Ответы на вопросы

  1. skipWaiting Этот метод заставляет установленный, но ещё ожидающий ServiceWorker активироваться сразу же.
  2. clients.claim Этот метод в паре с предыдущим "перетягивает" на себя "одеяло" активности с текущего активного ServiceWorker и позволяет работать с уже отрендеренной страницей, без необходимости её перезагрузки.
  3. url.origin + url.pathname Не для всех, потому что кроме адреса, к которому идёт обращение (и который по частям собирается этой формулой), могут также существовать параметры get-запроса. Для исправления такого поведения нужно изменить эту строку таким образом:
const cacheKey = url.origin + url.pathname + url.searchParams.toString();
  1. Цепочка вызовов в deleteObsoleteCaches Эта цепочка нужна для того, чтобы вычистить асинхронно всё в кэше, что не было сохранено текущей версией ServiceWorker'а. Promise здесь нужен, потому что caches.delete - асинхронный метод, результат которого надо дождаться, чтобы вернуть из функции deleteObsoleteCaches.
  2. Клонирование ответа от сервера Клонирование нужно, поскольку Body (тело запросов и ответов к/от сервера) возможно использовать только один раз. А нам нужно как минимум положить этот ответ в кэш и вернуть его обратно в браузер (чтобы отобразить картинку), т.е. использовать тело дважды.