Дайджесты новостей
Европейский комикс о разработчике браузера Chrome, радующемся безопасной интеграции декодера JPEG XL на Rust.

Декодирование JPEG XL в Chrome 155: безопасный Rust и SIMD-оптимизации jxl-rs

Борьба за идеальный графический формат для веба длится уже третье десятилетие. Мы начинали с классического JPEG, затем пережили эпоху WebP, а последние годы наблюдали за триумфальным шествием AVIF. Однако профессиональные фотографы, дизайнеры и веб-разработчики всё это время продолжали настойчиво требовать внедрения JPEG XL (.jxl) — формата, созданного Объединенной группой экспертов по фотографии специально на замену оригинальному стандарту 1992 года.

Судьба формата в самом популярном браузере мира напоминала настоящие американские горки. Несколько лет назад Google добавил экспериментальную поддержку JPEG XL, но уже в Chrome 110 внезапно вырезал флаг из кодовой базы, сославшись на то, что формат якобы «не демонстрирует достаточного преимущества перед AVIF, а его поддержка усложняет обслуживание браузера». Сообщество встретило это решение шквалом критики: петиция на баг-трекере Chromium собрала тысячи голосов, а в проекте кроссбраузерной стандартизации Interop 2026 поддержка JPEG XL заняла одно из первых мест по результатам голосования разработчиков.

И вот свершилось: в стабильном релизе Chrome 155 поддержка формата вернулась нативно и по умолчанию. Но самое интересное в этой новости — не политическая капитуляция перед веб-стандартами, а инженерная изнанка того, как устроен новый декодер.

Правило двух Chromium: почему C++ проиграл

Чтобы понять, почему внедрение JPEG XL заняло столько времени, нужно взглянуть на то, как браузер устроен с точки зрения информационной безопасности.

Медиа-декодеры — это исторически самое уязвимое место любого веб-браузера. Твой браузер скачивает произвольный бинарный файл с неизвестного сервера в интернете и тут же скармливает его сложнейшему алгоритму распаковки. Если в коде декодера допущена малейшая ошибка управления памятью — выход за границы массива, целочисленное переполнение или чтение освобожденного указателя (Use-After-Free) — злоумышленник может внедрить шелл-код и захватить контроль над процессом.

В Google действует строгое правило безопасности — Chromium Rule of Two:

  1. Код обрабатывает недоверенный пользовательский ввод из сети.
  2. Код исполняется без жесткой изоляции в песочнице (sandbox).
  3. Код написан на небезопасном по памяти языке (C/C++).

По правилам проекта, любая часть системы может удовлетворять максимум двум из этих трех условий одновременно. Оригинальная эталонная библиотека libjxl, написанная на C++, требовала огромных усилий по изолированию и постоянно генерировала потенциальные предупреждения безопасности при фаззинг-тестировании.

Инженеры Google (Лука Версари, Мориц Фиршинг и Филип Егенштедт) пошли по принципиально новому пути: они полностью отказались от C++ и интегрировали в движок Chromium независимый декодер jxl-rs, целиком написанный на безопасном системном языке Rust! За всё время непрерывного фаззинг-тестирования миллионами искаженных файлов в jxl-rs не было зафиксировано ни единого сбоя безопасности памяти.

Как выжать скорость без unsafe: магия target_feature_11

Но здесь перед инженерами встал второй фундаментальный барьер — производительность. Декодирование изображений высокого разрешения требует огромных вычислительных мощностей: если декодер на Rust будет работать медленнее C++, пользователи столкнутся с фризами интерфейса при прокрутке галерей.

Технический чертеж безопасного векторного конвейера target_feature_11 в компиляторе Rust для декодера jxl-rs.

В C++ для выжимания предельной скорости традиционно использовалась библиотека Google Highway, которая генерирует «сырые» инструкции векторных расширений процессора (SIMD: AVX2, AVX-512, ARM NEON). В Rust использование SIMD исторически требовало оборачивания каждой операции в блок unsafe, что перечеркивало саму идею перехода на безопасный язык.

Команда jxl-rs нашла изящный выход: они дождались и помогли стабилизировать в компиляторе Rust функцию target_feature_11. Этот механизм позволяет компилятору безопасно применять аппаратные векторные регистры конкретной архитектуры без единого вызова unsafe.

Поверх этого разработчики создали переносимый уровень абстракции jxl_simd. Вот как выглядит фрагмент безопасной параллельной обработки коэффициентов дискретного косинусного преобразования (DCT):

// Использование стабилизированной функциональности target_feature_11 в Rust
#[target_feature(enable = "avx2")]
pub fn process_dct_coefficients(input: &[f32], output: &mut [f32]) {
    assert_eq!(input.len(), output.len());
    
    // Векторные операции выполняются безопасно: границы массивов проверены,
    // а компилятор автоматически генерирует векторные инструкции AVX2 vmulps / vaddps
    for (in_chunk, out_chunk) in input.chunks_exact(8).zip(output.chunks_exact_mut(8)) {
        for i in 0..8 {
            out_chunk[i] = in_chunk[i] * 1.4142135;
        }
    }
}

Благодаря этому декодер jxl-rs на архитектурах x86-64 и ARM64 работает наравне с C++, не ставя под угрозу безопасность миллиардов пользователей браузера.

Чем хорош сам JPEG XL: не только мегабайты

Почему же разработчики так отчаянно боролись за возвращение формата? Дело в том, что JPEG XL решает задачи, с которыми не справляются ни WebP, ни AVIF:

  1. Сжатие без потерь (Lossless) и огромные разрешения: AVIF основан на видеокодеке AV1, у которого есть жесткие ограничения на максимальное разрешение кадра (до 4K/8K без сложного разбиения на тайлы) и посредственная работа в режиме сжатия без потерь. JPEG XL сжимает графику без потерь на 30–50% плотнее PNG и поддерживает полотна до сотен тысяч пикселей по стороне.
  2. Перепаковка старых JPEG без потерь: это киллер-фича формата. Любой существующий файл .jpg можно перепаковать в .jxl с экономией около 20% дискового пространства, причем это обратимая операция! Ты можешь в любой момент распаковать файл обратно в исходный JPEG с точностью до каждого оригинального бита. Для сервисов вроде Google Photos или облачных хранилищ это миллиарды долларов экономии на накопителях.
  3. Честный HDR и прогрессивность: формат проектировался с нативной поддержкой 16-битных цветовых каналов, широких цветовых охватов (Rec.2020) и плавной прогрессивной отрисовки, когда браузер сначала отображает размытый контур, а затем плавно догружает детали без дергания макета.

Как безопасно внедрять JPEG XL на сайте

Поскольку Safari уже поддерживает JPEG XL, а с выходом Chrome 155 суммарная доля браузеров с нативной поддержкой формата перевалила за 80%, его можно смело внедрять в продакшен.

Стандартный и самый безопасный способ — использование HTML-тега <picture> с каскадными фоллбэками:

<picture>
  <!-- Современные клиенты (Chrome 155+, Safari) загрузят сверхкомпактный JPEG XL -->
  <source srcset="/images/landscape-hdr.jxl" type="image/jxl">
  
  <!-- Альтернативный современный формат для браузеров с поддержкой AVIF -->
  <source srcset="/images/landscape-hdr.avif" type="image/avif">
  
  <!-- Проверенный WebP для широкой совместимости -->
  <source srcset="/images/landscape-hdr.webp" type="image/webp">
  
  <!-- Универсальный запасной вариант для устаревших клиентов -->
  <img 
    src="/images/landscape-hdr.jpg" 
    alt="Панорама горного хребта в лучах заката" 
    width="1920" 
    height="1080" 
    loading="lazy"
  >
</picture>

Браузер последовательно проверяет поддерживаемые типы контента сверху вниз и скачивает только первый подходящий файл.

Разумное разделение ролей: AVIF против JPEG XL

Не спеши тотально заменять AVIF на JPEG XL. Инженеры Google рекомендуют взвешенный подход: для небольших иллюстраций, логотипов и контента со средним битрейтом AVIF по-прежнему показывает отличные результаты. А вот для тяжелых фотографий в высоком разрешении, профессиональной графики и HDR-изображений безусловным лидером становится JPEG XL.

Возвращение JPEG XL в Chrome на безопасном движке Rust — это знаковая победа здравого смысла и открытых веб-стандартов. Мы получили не просто новый эффективный кодек, но и прецедент того, как критические подсистемы современных браузеров постепенно переписываются на безопасные языки без компромиссов по скорости.