Тимоти Никкел, разработчик Mozilla, сообщил в списке рассылки dev-platform о намерении включить декодирование JPEG XL по умолчанию во всех сборках Firefox начиная с версии 157. Формат разрабатывался за флагом image.jxl.enabled, который сейчас включён по умолчанию только в Nightly, а начиная с 152-й версии присутствует как переключатель в Firefox Labs на всех каналах. За декодирование отвечает библиотека jxl-rs, написанная на Rust.
Основные параметры
- Баг на включение по умолчанию: bugzilla.mozilla.org/show_bug.cgi?id=2065096
- Стандарт: ISO/IEC 18181, iso.org/standard/85066
- Орган стандартизации: ISO/IEC
- Охват платформ: все
- Настройка:
image.jxl.enabled - Позиция по стандартам: github.com/mozilla/standards-positions/issues/522 (нейтральная)
- Ревью TAG: github.com/w3ctag/design-reviews/issues/633 (удовлетворены с замечаниями)
- Намерение о прототипировании: ссылка на обсуждение
Среди других браузеров: Safari поставляет поддержку JPEG XL начиная с версии 17.0, выпущенной в 2023 году. В Chrome формат доступен за флагом #enable-jxl-image-format и использует ту же Rust-библиотеку, но намерения включить его по умолчанию пока не объявлено.
Что изменилось с момента прототипирования
На стадии прототипирования участники обсуждения высказывали опасения по поводу производительности. С тех пор вышла jxl-rs 0.6.0 с поддержкой многопоточного декодирования, а патчи для подключения и включения многопоточности ожидаются в ближайшее время. С учётом этих патчей Никкел провёл бенчмарк декодирования по пяти форматам на одних и тех же изображениях разного размера: на его машине результат немного превзошёл Safari (использующий C++-реализацию libjxl). По сравнению с другими декодерами изображений в Firefox, JXL показывает близкие результаты на крупных изображениях, но заметно отстаёт на маленьких.
По функциональности JXL сравним с другими форматами изображений в Firefox и с реализацией JXL в Blink, включая анимацию и прогрессивное отображение. Исключение — HDR: HDR-изображения отображаются как SDR, как и во всех остальных поддерживаемых форматах, однако тональное отображение (tone mapping) для JXL реализовано существенно лучше, чем для других форматов. У Safari при этом нет ни прогрессивного рендеринга, ни поддержки анимации.
Тестовый набор wpt для директории jpegxl охватывает корректность декодирования по битовой глубине, альфа-каналу, градациям серого, CMYK, управлению цветом, ориентации и инструментам кодирования, а также способы использования изображений в HTML и CSS. Там, где wpt не позволял выразить нужные сценарии, добавлены собственные тесты Gecko: около 30 gtest-тестов для чанкового и инкрементального декодирования, подсчёта кадров анимации, уменьшения размера при декодировании и обработки повреждённых файлов, mochitest-тесты для прогрессивного рендеринга и телеметрии, reftest-тесты и бенчмарки декодирования, отправляющие данные в Perfherder. Команда фаззинга уже тестировала jxl-rs до включения в Nightly и повторит фаззинг перед переключением настройки по умолчанию.
Реакция сообщества
В ответ на сообщение Никкела появился вопрос от пользователя под именем 一丝 о поддержке анимированного JPEG XL. Никкел подтвердил: анимация поддерживается.
Отдельно высказал опасения разработчик Сергей Давыдов, обративший внимание на производительность безлосслесс-режима (lossless) JPEG XL:
Меня беспокоит производительность lossless JPEG XL. По моим измерениям декодирование занимает в 30 раз больше времени, чем у lossless WebP, при выигрыше всего 10% в размере файла. Это спорный компромисс, особенно на ноутбуках и телефонах, где это может расходовать заряд батареи и ухудшать пользовательский опыт.
Предлагаю поставлять в Firefox 157 только lossy JPEG XL, а вопрос lossless-формата рассмотреть отдельно.
Давыдов привёл методику измерений: использовался инструмент hyperfine, который замеряет время выполнения на нескольких прогонах и собирает статистику. Тестировалась библиотека jxl-rs из репозитория github.com/libjxl/jxl-rs (коммит 775837f57dfe4294d89c1c6317dd91a1ed8d3cfa), собранная командой cargo build --release. В качестве исходного изображения использовалась картинка с Wikimedia Commons, сконвертированная в WebP командой cwebp -lossless и в JPEG XL — командой cjxl -d 0. Оба декодера запускались в однопоточном режиме для замера полного процессорного времени с помощью taskset -c 0.
$ hyperfine --warmup 5 'taskset -c 0 target/release/jxl_cli --speedtest 55_Cancri_e_Final_1_30.jxl' 'taskset -c 0 dwebp 55_Cancri_e_Final_1_30.png.webp'
Benchmark 1: taskset -c 0 target/release/jxl_cli --speedtest 55_Cancri_e_Final_1_30.jxl
Time (mean ± σ): 20.632 s ± 0.061 s [User: 20.605 s, System: 0.027 s]
Range (min … max): 20.549 s … 20.743 s 10 runs
Benchmark 2: taskset -c 0 dwebp 55_Cancri_e_Final_1_30.png.webp
Time (mean ± σ): 667.0 ms ± 2.2 ms [User: 449.5 ms, System: 217.5 ms]
Range (min … max): 664.3 ms … 670.1 ms 10 runs
Summary
taskset -c 0 dwebp 55_Cancri_e_Final_1_30.png.webp ran
30.93 ± 0.14 times faster than taskset -c 0 target/release/jxl_cli --speedtest 55_Cancri_e_Final_1_30.jxl
Для сравнения, инструмент djxl из libjxl показывает результат в 20 раз медленнее WebP при таком же тесте. По мнению Давыдова, это говорит о том, что дальнейшая оптимизация Rust-кода вряд ли сможет исправить ситуацию — общий расклад останется прежним.