npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@budarin/psw-plugin-serve-range-requests

v1.0.41

Published

Service Worker plugin for @budarin/pluggable-serviceworker that serves HTTP Range requests for cached files

Downloads

790

Readme

@budarin/psw-plugin-serve-range-requests

Плагин Service Worker для @budarin/pluggable-serviceworker, который обслуживает HTTP Range запросы для кэшированных файлов.

Если медиа кэшируется без поддержки Range-запросов, браузер вынужден загружать файл целиком в память и воспроизводить его с начала до конца. Перейти к другому месту (перемотка) при этом нельзя, а для больших файлов объём занятой памяти получается очень большим. На слабых или ограниченных по памяти устройствах это нередко приводит к подвисаниям, сбоям воспроизведения или даже падениям. Плагин добавляет корректную поддержку Range для кэшированного контента: читаются и отдаются только запрошенные диапазоны байтов, поэтому перемотка работает, а потребление памяти остаётся приемлемым.

Зачем нужен этот плагин

Приложения для воспроизведения и просмотра больших медиафайлов обычно запрашивают данные по частям (HTTP Range), а не целиком. Если такие файлы лежат в обычном кеше, на каждый запрос одного сегмента из кеша будет извлекаться и передаваться клиенту весь файл — лишняя нагрузка на память и процессор, из‑за которой приложение может тормозить. Плагин отдаёт из кеша только запрошенный диапазон байтов, поэтому воспроизведение остаётся плавным, а потребление ресурсов — умеренным.

Быстрый старт

В большинстве случаев достаточно выбрать готовый пресет и указать имя кеша. Остальные опции можно не трогать.

import { initServiceWorker } from '@budarin/pluggable-serviceworker';
import {
    serveRangeRequests,
    VIDEO_PRESET,
} from '@budarin/psw-plugin-serve-range-requests';

initServiceWorker(
    [serveRangeRequests({ ...VIDEO_PRESET, cacheName: 'video-cache' })],
    { version: '1.0.0' }
);

Минимальный вариант без пресета — только обязательный параметр:

serveRangeRequests({ cacheName: 'media-cache' });

Подробнее по сценариям (видео, карты, документы) — ниже. Все опции — в конце раздела.

Плагин обрабатывает только GET-запросы с заголовком Range, подходящие под фильтры include/exclude (если они заданы). Для каждого такого range-запроса плагин сам возвращает ответ: либо 206 из кэша (из полного файла или из кэша диапазонов), либо ответ из сети — при промахе кэша, при обходе бага Chromium (уже отдавали этот URL из сети в этой вкладке) или при наличии у клиента If-Range. Остальные запросы — без Range, не GET или не прошедшие фильтры — плагин не обрабатывает и передаёт следующим плагинам в цепочке.

Когда что кешировать — по сценариям

Плагин кеширует два типа данных: метаданные файлов (размер, тип) и готовые ответы по диапазонам. Но смысл кеширования диапазонов сильно зависит от того, как пользователь работает с контентом.

Видео и аудио: при перемотке кеш диапазонов не используется

При перемотке каждый переход (seek) запрашивает новый участок файла. Пользователь редко возвращается к тому же байтовому диапазону — плеер запрашивает другие смещения. Кеш диапазонов почти не попадает в повторные запросы и только занимает память.

Для видео и аудио ставьте maxCachedRanges в 0. Важнее: при перемотке браузер шлёт десятки запросов и отменяет старые. С prioritizeLatestRequest: true плагин отдаёт приоритет последнему запросу и отменяет лишнюю работу.

Документы (PDF и т.п.): кеш полезен при листании

Пользователь листает туда-сюда — одни и те же страницы запрашиваются повторно. Кеш диапазонов помогает. prioritizeLatestRequest: false — без очередей, все запросы параллельно.

Карты и тайлы: кеш очень полезен

При панорамировании и зуме запрашиваются одни и те же тайлы снова и снова. Один и тот же диапазон в pmtiles/mbtiles запрашивается многократно — кеш диапазонов даёт заметный выигрыш. Ставьте maxCachedRanges побольше (500–1000). prioritizeLatestRequest: false — без очередей, все запросы параллельно.


Кеш диапазонов (maxCachedRanges, maxCacheableRangeSize) Плагин кеширует готовые ответы по диапазонам и метаданные файлов (размер, тип) для тех же URL. maxCachedRanges ограничивает, сколько ответов и записей метаданных держать. maxCacheableRangeSize — верхняя граница на один диапазон; диапазоны крупнее не кешируются (защита от переполнения). Для видео и аудио при перемотках ставьте maxCachedRanges в 0 — кеш не используется.

Параллелизм (maxConcurrentRangesPerUrl) Действует только при prioritizeLatestRequest: true. Для видео и аудио оптимально 1 — очереди тормозят. При false ограничение не применяется — все запросы параллельно.

Приоритет последнего запроса (prioritizeLatestRequest) true (по умолчанию) — для видео и аудио: приоритет последнему запросу, отмена лишних при новом. false — для карт и документов: без очередей, все запросы выполняются параллельно.

Ответы 206 и кеш браузера По умолчанию плагин не выставляет заголовок Cache-Control для ответов 206. Чтобы разрешить кеширование в браузере, задайте rangeResponseCacheControl (например 'max-age=31536000, immutable'). Чтобы запретить кеширование — 'no-store'. Если опцию не задавать, заголовок не отправляется.

Для настройки ориентируйтесь на реальные запросы — смотрите Network в DevTools.

Все опции

Опции сгруппированы по смыслу. Значения по умолчанию подходят для большинства сценариев.

Основное

| Параметр | Тип | По умолчанию | Описание | | ----------- | -------- | ------------ | ---------------------------------------- | | cacheName | string | — | Обязательно. Имя кеша. | | order | number | -10 | Опционально. Порядок выполнения плагина. |

Кеш диапазонов и память

| Параметр | Тип | По умолчанию | Описание | | ----------------------- | -------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------ | | maxCachedRanges | number | 100 | Макс. число закешированных ответов по диапазонам (и записей метаданных). Для видео при перемотке обычно 0. Для карт/документов — 500–1000. | | maxCacheableRangeSize | number | 10MB | Макс. размер одного кешируемого диапазона; большие не кешируются. | | maxTrackedUrls | number | 512 | Максимум разных файлов (URL), по которым плагин учитывает ограничение одновременных запросов. Ограничивает рост памяти при большом числе файлов. |

Параллелизм и приоритет

| Параметр | Тип | По умолчанию | Описание | | --------------------------- | --------- | ------------ | ---------------------------------------------------------------------- | | maxConcurrentRangesPerUrl | number | 4 | Сколько диапазонов одного файла читать параллельно. Для видео часто 1. | | prioritizeLatestRequest | boolean | true | Приоритет последнему запросу (видео/аудио). false — карты/документы. |

Фильтры

| Параметр | Тип | По умолчанию | Описание | | --------- | ---------- | ------------ | --------------------------------------------- | | include | string[] | — | Маски файлов (glob). Только эти обрабатывать. | | exclude | string[] | — | Маски файлов (glob). Исключить из обработки. |

Восстановление и отдача

| Параметр | Тип | По умолчанию | Описание | | --------------------------- | ---------- | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | restoreMissingToCache | boolean | true | При отсутствии файла в кеше: отдать запрос из сети и в фоне загрузить полный файл в кеш для следующих запросов. | | assets | string[] | — | Пути к ресурсам (например /assets/Meeting.mp4), не полные URL — при сборке домен неизвестен. Если список задан: фоновое восстановление в кеш только для запросов, путь которых входит в этот список. | | rangeResponseCacheControl | string | — | Необязательный Cache-Control для ответов 206 (например 'max-age=31536000, immutable' для кеширования в браузере). Если не задан, заголовок не отправляется. |

Отладка

| Параметр | Тип | По умолчанию | Описание | | --------------- | --------- | ------------ | --------------- | | enableLogging | boolean | false | Подробные логи. |

Важные моменты

⚠️ Не кешируйте огромные файлы и диапазоны — мобильные устройства могут не справиться с ними. Данные диапазона читаются из потока кешированного файла последовательно (Cache API не поддерживает произвольный доступ), поэтому запрос диапазона в конце очень большого файла может выполняться долго; предпочтительны более мелкие ресурсы.

Один источник на URL в рамках вкладки (обход бага Chromium) — В Chromium при смене источника в середине воспроизведения (сначала сеть, затем ответы из кэша SW) медиа-пайплайн игнорирует ответ из кэша и воспроизведение падает с PIPELINE_ERROR_READ. Поэтому плагин для каждого URL в рамках вкладки не переключает источник: если по этому URL в этой вкладке уже отдавали из сети (например, файла не было в кэше), все последующие запросы по этому URL в той же вкладке идут в сеть до перезагрузки страницы, даже когда файл уже восстановлен в кэш. После перезагрузки при наличии файла в кэше отдача идёт из кэша. Подробнее: Chromium bug #1026867, тест-кейс phoboslab.

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

С пресетами (рекомендуется):

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' }
);

Ручная настройка (если нужно подкрутить под себя):

serveRangeRequests({
    cacheName: 'media-cache',
    include: ['*.mp4', '*.webm', '*.mkv'],
    maxCachedRanges: 0,
    maxConcurrentRangesPerUrl: 1,
    prioritizeLatestRequest: true,
});

Готовые пресеты (опционально)

Если не хотите настраивать параметры вручную, используйте готовые пресеты:

Доступные пресеты

  • 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 { getAdaptivePresets } from '@budarin/psw-plugin-serve-range-requests';

const { VIDEO_ADAPTIVE, AUDIO_ADAPTIVE, MAPS_ADAPTIVE, DOCS_ADAPTIVE } =
    getAdaptivePresets();
// Использовать так же: { ...VIDEO_ADAPTIVE, cacheName: 'video-cache' }

Поддерживаемые Range форматы

  • bytes=0-499 — первые 500 байтов
  • bytes=500-999 — байты с 500 по 999
  • bytes=500- — от 500 байта до конца
  • bytes=-500 — последние 500 байтов

Как это работает

  1. Проверяет заголовок Range в запросе
  2. Ищет файл в указанном кеше
  3. Если файл есть в кеше: плагин отдаёт из кэша только когда для этой вкладки и URL источник не меняется; иначе запрос передаётся в сеть (обход бага Chromium #1026867).
  4. При отсутствии файла плагин отдаёт запрос из сети и при restoreMissingToCache: true в фоне загружает полный файл в кеш для следующих запросов только если путь запроса входит в assets (если assets задан; иначе — для любого URL). В этой вкладке все последующие запросы по этому URL идут в сеть до перезагрузки страницы.
  5. Читает нужный диапазон из файла и возвращает HTTP 206 (Partial Content). При включённом кешировании диапазонов ответ сохраняется для повторного использования.

🤝 License

MIT © budarin