【Rust日报】2026-10-08 Chrome 用 jxl-rs 上线 JPEG XL

💡 原文中文,约3400字,阅读约需9分钟。
📝

内容提要

Chrome 155 起通过纯 Rust 解码器 jxl-rs 支持 JPEG XL,压缩率较 JPEG 高 30%–50%,并支持无损与 HDR。rustc 1.99 存在 bool FFI 返回值缺掩码的误编译问题。derive(Debug) 常带 #[inline],易导致体积膨胀。Zizq 任务队列改用内存索引后,出队耗时从 40 毫秒降至 4 微秒。

🔎

延伸解读

JPEG XL 在 Chrome 中的定位与选择

Chrome 155 起通过纯 Rust 解码器 jxl-rs 支持 JPEG XL,其压缩率比 JPEG 高 30%–50%,并支持无损压缩、HDR 以及将 JPEG 无损转为 JPEG XL。文章建议同时尝试 AVIF 和 JPEG XL,但 JPEG XL 更适用于高保真或无损压缩场景,尤其是照片和需要细粒度渐进解码的场景。这意味着在图片格式选型时,JPEG XL 并非 AVIF 的替代,而是互补,开发者应根据内容类型和需求选择。

jxl-rs 的内存安全与性能优化

jxl-rs 是一套纯 Rust 的 JPEG XL 解码器,被 Chrome 集成以处理 C++ 解码器中常见的越界读、堆溢出和 use-after-free 问题。它使用已稳定的 target_feature_11,调用 SIMD 指令时无需 unsafe,并将 unsafe 限制在少量经过检查的位置。性能优化沿用 libjxl,包括跨区域边界的处理管线和减少数据拷贝。文章提到,fuzzing 和 AI review 未在 jxl-rs 的实现历史中发现内存安全缺陷,这增强了其可靠性。

rustc 1.99.0 的 FFI bool 返回值误编译风险

rustc 1.99.0 存在一个误编译问题:当 Rust 函数通过 FFI 返回 bool 时,生成的汇编缺少掩码操作,导致返回值的高位可能保留入参的垃圾数据。例如,传入 0x10 时,期望返回 0,实际返回 16。该问题在 x86_64 Linux 上可复现,影响 1.99.0 和 nightly 1.101.0-nightly,而 aarch64 和 loongarch64 不受影响。根据 x86-64 psABI,bool 返回值的 bit 1 到 bit 7 必须为 0,因此当前实现违反了 ABI。使用

derive(Debug) 内联导致的二进制膨胀

Rust 的 #[derive(Debug)] 展开后,生成的 fmt 方法通常带有 #[inline] 提示,这可能导致短小的 Debug 实现被内联。对于嵌套的错误类型,每一层 Debug 都标有 #[inline],每次 Debug 调用都可能将整棵实现内联进去,从而显著增加二进制体积。文章中的例子显示,在 uv 项目中用 #[inline(never)] 替换 derive(Debug) 后,二进制大约减小了 160KB。rustc 似乎没有对 Debug 实现的体积或内联次数设置上限,因此开发者应关注嵌套

❓

Q&A

Chrome 从哪个版本开始支持 JPEG XL?

从 Chrome 155 起,Chrome 开始解码 .jxl 文件。

JPEG XL 相比 JPEG 有哪些优势?

JPEG XL 的压缩率比 JPEG 高 30% 到 50%,支持无损压缩、HDR,以及把 JPEG 无损转成 JPEG XL。

rustc 1.99.0 的 FFI bool 返回值误编译问题是什么?

在 x86_64 Linux 上,Rust 函数返回 bool 时缺少掩码操作,导致返回值高位包含入参的无关位。例如传入 0x10 时,期望返回 0,实际返回 16。

derive(Debug) 为什么会导致二进制体积膨胀?

因为 #[derive(Debug)] 展开后的实现经常带有 #[inline] 属性,嵌套错误类型时,每次 Debug 都可能把整棵实现内联进去,导致体积增大。

Zizq 如何将出队耗时从 40 毫秒降到 4 微秒?

Zizq 将 ready 索引从 LSM tree 移到内存中,避免了扫描 tombstone 的开销,从而将出队耗时从约 40 毫秒降至约 4 微秒。

Zizq 如何改进 worker 断线检测?

Zizq 默认将 TCP_USER_TIMEOUT 设为 30 秒,与官方客户端 30 秒无数据即重连对齐,使任务回到 ready 的时间从 943 秒缩短到 30 秒多一点。

🏷️

标签

➡️

继续阅读