← На главную

ZGIF ускорил сжатие GIF с 4 минут до 4 секунд, обойдя flexiGIF

23.06.2026 12:56 · hackernews

Автор решил, что его сайт 1-Click Linux будет выглядеть прилично даже в древних браузерах вроде NCSA Mosaic или Netscape. Для этого он использовал тег <picture> с запасным вариантом в виде GIF — формата, который поддерживается абсолютно везде. Проблема в том, что GIF использует сжатие LZW, и оно не впечатляет. В 2026 году для веба логичнее использовать SVG и WebP, но если хочешь поддерживать реально старые браузеры — придётся возиться с GIF.

Можно уменьшить размер картинки — старые экраны крошечные, 128×128 пикселей хватит. Ещё можно выкинуть метаданные, убрать лишние цвета из палитры. Но это всё косметика. Настоящая оптимизация сжатия — другая история.

Автор вспомнил про ZopfliPNG. Эта утилита перебирает все возможные синтаксически корректные DEFLATE-потоки (тот же LZ77 + Huffman) и находит действительно наилучший вариант. Для PNG это работает отлично, но для GIF такого инструмента не было — пока не появился flexiGIF. Он делает то же самое, но для LZW. И всё бы хорошо, но автор заметил странную пометку в README flexiGIF: иногда файлы получаются больше, чем у оригинального алгоритма.

Автор разобрался. LZW устроен так: сжатый поток состоит из команд — либо «выдай байт», либо «повтори предыдущую последовательность и добавь первый байт следующей». Обычный жадный алгоритм каждый раз берёт самую длинную подходящую последовательность. Это даёт локальный оптимум, но не глобальный. flexiGIF пытается заглядывать на шаг вперёд, откладывая решение. Но это приводит к тому, что словарь LZW заполняется пустышками — и некоторые последовательности становятся невозможны. Отсюда и парадокс: двухшаговый просмотр может дать результат хуже, чем простой жадный.

Тогда автор написал собственный инструмент — ZGIF. Он решил перебрать все возможные варианты — настоящий глобальный поиск. На Python. Итог: 4 минуты на сжатие картинки 16×16 пикселей (256 байт). Это «ледниково медленно». Он переписал код несколько раз, пробуя A*, динамическое программирование и гибридный поиск с отсечениями. В итоге отключил полный перебор и ограничился одношаговым просмотром — зато скорость упала с 4 минут до 4 секунд. Результаты всё ещё лучше, чем у flexiGIF. Код лежит на SourceHut. Он грязный, но по истории коммитов видно, как автор шёл к решению.

Читать оригинал →