@budarin/psw-plugin-serve-range-requests
v1.0.10
Published
Service Worker plugin for @budarin/pluggable-serviceworker that serves HTTP Range requests for cached files
Maintainers
Readme
@budarin/psw-plugin-serve-range-requests
Плагин Service Worker для @budarin/pluggable-serviceworker, который обслуживает HTTP Range запросы для кэшированных файлов.
Зачем нужен этот плагин
Приложения для воспроизведения и просмотра больших медиафайлов обычно запрашивают данные по частям (HTTP Range), а не целиком. Если такие файлы лежат в обычном кеше, на каждый запрос одного сегмента из кеша будет извлекаться и передаваться клиенту весь файл — лишняя нагрузка на память и процессор, из‑за которой приложение может тормозить. Плагин отдаёт из кеша только запрошенный диапазон байтов, поэтому воспроизведение остаётся плавным, а потребление ресурсов — умеренным.
Быстрый старт
import { serveRangeRequests } from '@budarin/psw-plugin-serve-range-requests';
// Базовое использование - только обязательный параметр
serveRangeRequests({ cacheName: 'media-cache' });
// С дополнительными настройками
serveRangeRequests({
cacheName: 'media-cache',
include: ['*.mp4', '*.mp3', '*.pdf'], // Только эти типы файлов
maxCacheableRangeSize: 5 * 1024 * 1024, // Максимум 5MB на диапазон
maxCachedRanges: 50, // Максимум 50 диапазонов в памяти
enableLogging: true, // Включить логи для отладки
});Опции
| Параметр | Тип | По умолчанию | Описание |
| --------------------------- | ---------- | ----------------------------- | ---------------------------------------------------------------------------------------------- |
| cacheName | string | - | Обязательно. Имя кеша |
| order | number | -10 | Порядок выполнения (опционально) |
| maxCachedRanges | number | 100 | Макс. число кешируемых диапазонов (см. ниже) |
| maxCachedMetadata | number | 200 | Макс. число файлов, для которых хранятся метаданные (см. ниже) |
| maxCacheableRangeSize | number | 10MB | Макс. размер одной кешируемой записи (см. ниже) |
| include | string[] | - | Маски файлов (glob) |
| exclude | string[] | - | Исключения (glob) |
| rangeResponseCacheControl | string | max-age=31536000, immutable | Cache-Control для ответов 206 (кеш браузера); можно задать no-store, max-age=3600 или '' |
| enableLogging | boolean | false | Подробные логи |
Кеш метаданных (maxCachedMetadata)
Плагин запоминает метаданные уже обработанных файлов, чтобы быстрее отвечать на повторные Range-запросы к ним. Задайте значение примерно равным тому, сколько разных файлов данного типа пользователь обычно открывает или проигрывает за сессию. Если часто переключаются между многими файлами (длинный плейлист, большой каталог документов) — ставьте больше (сотни). Если обычно работают с немногими файлами — достаточно меньшего значения (десятки). Размер самих файлов на этот лимит не влияет, учитывается только количество разных URL.
Кеш диапазонов Плагин кеширует каждый отданный диапазон: повторные запросы к тому же месту файла (перемотка, повтор) отдаются из памяти. Вытеснение по LRU — при переполнении удаляются давно не используемые (самые старые) записи. maxCachedRanges — сколько диапазонов хранить; maxCacheableRangeSize — только верхняя граница: диапазоны крупнее не кешируются (защита от переполнения памяти). Минимального размера нет — кешируется любой запрошенный диапазон, не превышающий cap.
Ответы 206 и кеш браузера
По умолчанию на ответы 206 выставляется Cache-Control: max-age=31536000, immutable, чтобы браузер кешировал их. Задайте rangeResponseCacheControl (например no-store, max-age=3600 или ''), чтобы переопределить или не выставлять заголовок.
Для настройки параметров плагина ориентируйтесь на показатели запросов ваших ресурсов. Посмотреть и проанализировать все запросы к вашим ресурсам вы можете в DevTools браузера в разделе Network.
Важные моменты
⚠️ Не кешируйте огромные файлы и диапазоны — мобильные устройства могут не справиться с ними. Данные диапазона читаются из потока кешированного файла последовательно (Cache API не поддерживает произвольный доступ), поэтому запрос диапазона в конце очень большого файла может выполняться долго; предпочтительны более мелкие ресурсы.
Пример использования
import { initServiceWorker } from '@budarin/pluggable-serviceworker';
import { serveRangeRequests } from '@budarin/psw-plugin-serve-range-requests';
initServiceWorker(
[
serveRangeRequests({
cacheName: 'media-cache',
include: ['*.mp4', '*.webm', '*.mkv'], // Видео
maxCacheableRangeSize: 20 * 1024 * 1024, // 20MB
maxCachedRanges: 30,
}),
serveRangeRequests({
cacheName: 'media-cache',
include: ['*.mp3', '*.flac', '*.wav'], // Аудио
maxCacheableRangeSize: 8 * 1024 * 1024, // 8MB
maxCachedRanges: 200,
}),
],
{ version: '1.0.0' }
);Готовые пресеты (опционально)
Если не хотите настраивать параметры вручную, используйте готовые пресеты:
Доступные пресеты
- VIDEO_PRESET – для медиаплееров:
*.mp4,*.webm,*.mkv,*.avi,*.mov,*.m4v - AUDIO_PRESET – для аудиоплееров:
*.mp3,*.flac,*.wav,*.m4a,*.ogg,*.aac - MAPS_PRESET – для карт и тайлов:
*.mbtiles,*.pmtiles,/tiles/*,/maps/*,*.mvt - DOCS_PRESET – для документов:
*.pdf,*.epub,*.djvu,*.mobi,*.azw3
import { initServiceWorker } from '@budarin/pluggable-serviceworker';
import {
serveRangeRequests,
VIDEO_PRESET,
AUDIO_PRESET,
} from '@budarin/psw-plugin-serve-range-requests';
initServiceWorker(
[
serveRangeRequests({ ...VIDEO_PRESET, cacheName: 'video-cache' }),
serveRangeRequests({ ...AUDIO_PRESET, cacheName: 'audio-cache' }),
],
{ version: '1.0.0' }
);Адаптивные пресеты
Все пресеты можно адаптировать под характеристики устройства. На устройствах с малым объёмом памяти и слабым процессором лимиты автоматически снижаются.
import { initServiceWorker } from '@budarin/pluggable-serviceworker';
import {
serveRangeRequests,
getAdaptivePresets,
} from '@budarin/psw-plugin-serve-range-requests';
// Автоматически подстраивается под устройство:
// - Очень слабые (<2GB RAM и <2 ядра): минимальные лимиты
// - Слабые (<4GB RAM или <4 ядра): сниженные лимиты
// - Мощные (>=4GB RAM и >=4 ядра): полные настройки пресетов
const { VIDEO_ADAPTIVE, AUDIO_ADAPTIVE, MAPS_ADAPTIVE, DOCS_ADAPTIVE } =
getAdaptivePresets();
initServiceWorker(
[
serveRangeRequests({ ...VIDEO_ADAPTIVE, cacheName: 'video-cache' }),
serveRangeRequests({ ...AUDIO_ADAPTIVE, cacheName: 'audio-cache' }),
serveRangeRequests({ ...MAPS_ADAPTIVE, cacheName: 'maps-cache' }),
serveRangeRequests({ ...DOCS_ADAPTIVE, cacheName: 'docs-cache' }),
],
{ version: '1.0.0' }
);Поддерживаемые Range форматы
bytes=0-499- первые 500 байтовbytes=500-999- байты с 500 по 999bytes=500-- от 500 байта до концаbytes=-500- последние 500 байтов
Как это работает
- Проверяет заголовок Range в запросе
- Ищет файл в указанном кеше
- При наличии If-Range (ETag или Last-Modified) отдаёт из кеша только при совпадении сохранённого валидатора (иначе передаёт запрос дальше)
- Читает нужный диапазон из файла
- Кеширует готовый ответ для повторного использования
- Возвращает HTTP 206 (Partial Content)
Совет: Для большинства случаев достаточно базовой конфигурации с указанием cacheName и include паттернов!
🤝 License
MIT © budarin
