Как sw-precache генерирует хэши файлов

Библиотека sw-precache использует хэширование файлов для управления кэшированием ресурсов в сервис-воркере. Этот механизм позволяет эффективно отслеживать изменения файлов и обновлять кэш только при необходимости, минимизируя нагрузку на сеть и ускоряя загрузку страниц.

При генерации хэшей sw-precache последовательно обрабатывает каждый указанный файл из массива staticFileGlobs или из других источников ресурсов. Для вычисления хэша используется алгоритм MD5, что обеспечивает уникальность значения для каждой версии содержимого файла. Даже одна изменённая буква в файле приведёт к изменению хэша, что сигнализирует сервис-воркеру о необходимости обновления кэша.

const swPrecache = require('sw-precache');

swPrecache.write('service-worker.js', {
  staticFileGlobs: [
    'dist/**/*.js',
    'dist/**/*.css',
    'dist/**/*.html'
  ],
  stripPrefix: 'dist/'
});

В примере выше файлы из каталога dist будут просканированы, и для каждого будет рассчитан MD5-хэш. Этот хэш будет включён в манифест кэша, создаваемый сервис-воркером.


Формат записи хэшей в манифест

После вычисления хэшей sw-precache формирует объект precacheConfig, который содержит пары URL файла — хэш. Пример фрагмента:

[
  ["/css/main.css", "d41d8cd98f00b204e9800998ecf8427e"],
  ["/js/app.js", "e4d909c290d0fb1ca068ffaddf22cbd0"]
]

Каждая запись обеспечивает точное определение версии ресурса. При загрузке сервис-воркер проверяет наличие файла в кэше и сравнивает хэш. Если хэш отличается, файл обновляется. Такой подход исключает избыточное скачивание неизменённых ресурсов.


Настройка хэширования

sw-precache позволяет влиять на процесс хэширования через опции конфигурации:

  • dontCacheBustUrlsMatching — регулярное выражение, определяющее файлы, для которых не нужно добавлять контрольную сумму в URL. Полезно для внешних библиотек с постоянным именем, но часто меняющимся содержимым.
  • cacheId — префикс для кэша, который влияет на формирование ключей, связанных с хэшами.
  • stripPrefix — убирает лишние части пути, чтобы хэши соответствовали относительным URL в приложении.

Пример использования:

swPrecache.write('service-worker.js', {
  staticFileGlobs: ['dist/**/*.*'],
  stripPrefix: 'dist/',
  dontCacheBustUrlsMatching: /vendor\//,
  cacheId: 'my-app'
});

Здесь файлы из vendor/ не получают дополнительной контрольной суммы в URL, а все остальные — кэшируются с хэшами.


Алгоритм генерации и интеграция с сервис-воркером

  1. Сбор файлов: sw-precache сканирует указанные пути и фильтрует файлы по маске.
  2. Чтение содержимого: каждый файл считывается в память для вычисления хэша.
  3. Вычисление MD5: на основе байтового содержимого формируется уникальный хэш.
  4. Формирование precacheConfig: создаётся массив пар [URL, хэш].
  5. Генерация service-worker.js: шаблон сервис-воркера заполняется данными из precacheConfig.
  6. Сравнение и обновление кэша: при установке сервис-воркера проверяются хэши и обновляются только изменённые файлы.

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


Особенности работы с бинарными и текстовыми файлами

sw-precache одинаково корректно обрабатывает текстовые и бинарные файлы. В случае бинарных данных хэш также вычисляется по точным байтам, что обеспечивает контроль версий для изображений, шрифтов и других статических ресурсов. Это особенно важно для приложений с большим количеством медиа, где перекачивание неизменённых файлов критично с точки зрения производительности.


Влияние хэшей на стратегию кэширования

Контрольные суммы файлов позволяют сервис-воркеру использовать стратегию cache-first с верификацией версии. Даже если ресурс присутствует в кэше, проверка хэша гарантирует актуальность:

  • Файл с совпадающим хэшем — используется из кэша без запроса на сервер.
  • Файл с изменённым хэшем — перезагружается и обновляет кэш.

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


Оптимизация и масштабирование

Для больших проектов рекомендуется:

  • Разбивать staticFileGlobs на категории (CSS, JS, медиа), чтобы ускорить сканирование.
  • Использовать stripPrefix для сокращения длины URL в кэше.
  • Исключать редко изменяемые библиотеки через dontCacheBustUrlsMatching.
  • Генерировать сервис-воркер в процессе сборки (Webpack, Gulp, Grunt) для автоматической актуализации хэшей.

Эти практики уменьшают нагрузку на файловую систему и ускоряют установку сервис-воркера на клиенте.

Хэши остаются основой надёжного кэширования: правильная настройка и понимание их работы позволяет строить масштабируемые и быстрые PWA с точным контролем версий.