Precaching и одностраничные приложения

Precaching — это механизм, позволяющий заранее кэшировать ресурсы приложения на этапе установки сервис-воркера, обеспечивая мгновенный доступ к ним без необходимости сетевых запросов. В контексте одностраничных приложений (SPA) это особенно важно, так как SPA часто загружают основное приложение один раз, а затем динамически обновляют содержимое без полной перезагрузки страницы.

Регистрация и установка сервис-воркера

Для начала необходимо создать сервис-воркер и подключить библиотеку Workbox через CDN или npm-пакет.

Пример регистрации сервис-воркера в main.js:

if ('serviceWorker' in navigator) {
  window.addEventListener('load', () => {
    navigator.serviceWorker.register('/sw.js').then(registration => {
      console.log('Service Worker зарегистрирован с областью:', registration.scope);
    }).catch(error => {
      console.error('Ошибка при регистрации Service Worker:', error);
    });
  });
}

В sw.js подключается Workbox:

importScripts('https://storage.googleapis.com/workbox-cdn/releases/6.6.2/workbox-sw.js');

if (workbox) {
  console.log("Workbox загружен успешно");
} else {
  console.log("Workbox не загружен");
}

Конфигурация Precaching

Основной инструмент Workbox для precaching — workbox-precaching. Он позволяет указать список файлов и их версии, чтобы сервис-воркер мог их хранить и обновлять при изменении контента.

import { precacheAndRoute } from 'workbox-precaching';

// Массив файлов для кэширования
precacheAndRoute([
  { url: '/', revision: '123456' },
  { url: '/index.html', revision: '123456' },
  { url: '/styles/main.css', revision: '123456' },
  { url: '/scripts/main.js', revision: '123456' }
]);

Пояснения к коду:

  • url — путь к ресурсу.
  • revision — уникальный идентификатор версии файла. При изменении файла необходимо обновить ревизию, чтобы Workbox обновил кэш.

Стратегии обновления кэша

Workbox позволяет выбирать стратегии работы с кэшем для разных типов ресурсов:

  • Cache First — сначала проверяет кэш, если ресурс найден — отдает его, иначе делает сетевой запрос.
  • Network First — сначала делает сетевой запрос, при неудаче возвращает кэш.
  • Stale While Revalidate — возвращает кэш мгновенно, а в фоне обновляет его из сети.

Для SPA оптимальным является Stale While Revalidate для JS и CSS, а для API-запросов — Network First.

import { registerRoute } from 'workbox-routing';
import { StaleWhileRevalidate } from 'workbox-strategies';

registerRoute(
  ({ request }) => request.destination === 'script' || request.destination === 'style',
  new StaleWhileRevalidate()
);

Обработка маршрутов SPA

SPA обычно используют маршрутизацию на стороне клиента. В этом случае при запросе любого пути, который не соответствует статическому файлу, сервис-воркер должен отдавать index.html.

import { createHandlerBoundToURL } from 'workbox-precaching';
import { registerRoute } from 'workbox-routing';

const handler = createHandlerBoundToURL('/index.html');

registerRoute(
  ({ request, url }) => request.mode === 'navigate',
  handler
);

Особенности:

  • Все запросы на навигацию перенаправляются на index.html.
  • Позволяет SPA корректно обрабатывать маршруты без 404 ошибок при обновлении страницы.

Автоматическое обновление кэша

Workbox автоматически следит за ревизиями файлов. Когда файл меняется, новый сервис-воркер устанавливается, а старый активируется после того, как все вкладки закроются. Для ускорения активации можно использовать метод skipWaiting() и clientsClaim().

workbox.core.skipWaiting();
workbox.core.clientsClaim();

Отладка и анализ

Для проверки работы precaching и стратегии кэширования полезны:

  • Панель Application в DevTools → Service Workers и Cache Storage.
  • Логирование в сервис-воркере с console.log.
  • Использование workbox-precaching.cleanupOutdatedCaches() для автоматической очистки старых кэшей.
import { cleanupOutdatedCaches } from 'workbox-precaching';

cleanupOutdatedCaches();

Это предотвращает накопление устаревших ресурсов и экономит место на клиенте.

Интеграция с билдером

Для крупных SPA часто используют Webpack с плагином workbox-webpack-plugin, который автоматически генерирует список precache файлов с хэшами.

const { InjectManifest } = require('workbox-webpack-plugin');

module.exports = {
  // конфигурация Webpack...
  plugins: [
    new InjectManifest({
      swSrc: './src/sw.js',
      swDest: 'sw.js',
    }),
  ],
};

Преимущества:

  • Нет необходимости вручную обновлять ревизии файлов.
  • Поддержка больших проектов с сотнями статических ресурсов.

Особенности работы с динамическим контентом

Для SPA важно различать статические и динамические ресурсы:

  • Статические — JS, CSS, HTML, шрифты. Кэшируются через precaching.
  • Динамические — данные с API. Используются runtime стратегии (Network First, Stale While Revalidate).

Это предотвращает устаревание данных и обеспечивает быстрое отображение интерфейса при повторных загрузках.

Рекомендации по безопасности

  • Всегда указывать ревизии для файлов precache, чтобы изменения контента корректно обновлялись.
  • Использовать HTTPS для корректной работы сервис-воркеров.
  • Проверять размер кэша и очищать устаревшие версии, чтобы не перегружать устройство пользователя.

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