Skip to content

Справочник ​

Архитектура ​

Три npm-пакета делят одно ядро. hazehash содержит весь кодек: энкодер, который уменьшает изображение в линейном свете, переводит его в OKLab и описывает отдельными сетками DCT для яркости и цвета, выбирает квантование поиском «скорость–искажение», укладывающим результат в бюджет, и записывает коэффициенты кодированием Голомба–Райса, и декодер, который делает обратное. В нём же лежат тонкие платформенные слои: hazehash/canvas (рисует в canvas), hazehash/node (читает файлы изображений через необязательную peer-зависимость sharp) и команда hazehash. Файлы ядра никогда не трогают window, document, Buffer, eval и динамический import(), и это проверяет тест.

hazehash-vue это тонкий слой поверх декодера: composable usePlaceholder(), который держит цвет, соотношение сторон и ref canvas, и построенный на нём компонент PlaceholderImage. hazehash-nuxt регистрирует этот компонент, при сборке сканирует ваши папки с картинками через hazehash/node, кэширует хеши по размеру и времени изменения файла и отдаёт их компоненту как виртуальный модуль.

Формат хеша описан на странице Формат хеша, а сделанные в нём выборы измерены на странице Бенчмарк.

Совместимость с SSR ​

Декодер и энкодер это обычные функции без доступа к окружению, поэтому они работают на сервере. Браузер нужен только для рисования в canvas. Компонент и composable для Vue написаны с расчётом на серверный рендеринг: на сервере они выдают только background-color (средний цвет) и aspect-ratio, а canvas добавляется после монтирования, поэтому серверная разметка и первый клиентский рендер одинаковы и расхождения при гидрации невозможны. Обёртка <ClientOnly> не нужна ни в Nuxt, ни где-либо ещё.

Доступность ​

Canvas с размытым превью декоративный и помечен aria-hidden="true", поэтому вспомогательные технологии читают только настоящее изображение и его текст alt. Плавное проявление настоящей картинки отключается, если посетитель предпочитает уменьшенное движение (prefers-reduced-motion: reduce).

Размер бандла и peer-зависимости ​

Размеры даны после минификации и gzip и включают общий код, который импортирует каждая точка входа:

  • hazehash и hazehash/decode — около 2,6 КБ
  • hazehash/encode — около 6,3 КБ
  • hazehash/canvas — около 0,05 КБ поверх декодера

Каждый пакет публикуется с sideEffects: false, так что сборщик оставляет только импортированное. У hazehash нет зависимостей времени выполнения и одна необязательная peer-зависимость, sharp (>=0.33), которую используют только hazehash/node, командная строка и генерация хешей при сборке в модуле Nuxt. У hazehash-vue peer-зависимости hazehash и vue (^3.3.0). hazehash-nuxt зависит от @nuxt/kit, hazehash и hazehash-vue и имеет peer-зависимости nuxt (^3.9.0) и необязательный sharp. Все три поддерживают Node.js 20 и новее.

Сравнение ​

HazeHash решает ту же задачу, что BlurHash и ThumbHash: короткая строка, которая заменяет изображение, пока оно не загрузилось.

  • Качество — при том же размере средняя перцептивная ошибка у HazeHash примерно на 49% ниже, чем у BlurHash, и на 20% ниже, чем у ThumbHash, а при 20 байтах, размере хеша ThumbHash, он всё равно лучше на 14%. См. Бенчмарк.
  • Размер — бюджет от 16 до 48 байт, по умолчанию 28, против родного выхода ThumbHash около 21 байта и строк BlurHash, которые растут вместе с сеткой.
  • Прозрачность — альфа-канал хранится только тогда, когда он нужен изображению.
  • Соотношение сторон — хранится в заголовке, так что рамку можно рассчитать по одному хешу.
  • Формат — новый формат, не совместимый ни с одним из них; HazeHash нельзя декодировать как BlurHash или ThumbHash и наоборот. Существующие хеши придётся создавать заново из исходных изображений.

Разработка ​

Рабочее пространство pnpm с packages/core, packages/vue и packages/nuxt, а также демо на Nuxt, скрипты бенчмарка, примеры и сквозные тесты. Для сборки нужны Node.js 22 и pnpm.

bash
pnpm install
pnpm build       # все пакеты
pnpm test        # сборка, затем модульные тесты core, vue и nuxt
pnpm typecheck
pnpm lint
pnpm e2e         # Chromium, Firefox, WebKit, среда Cloudflare Workers, Nuxt SSR
pnpm demo        # приложение на Nuxt с 17 картинками рядом с их плейсхолдерами
pnpm bench       # полный бенчмарк

У пакета core есть ещё size (размеры бандлов), fuzz и make-vectors (зафиксированные векторы соответствия, которые скрипт отказывается перезаписывать).

Лицензия ​

MIT.