在上篇博文中,我分享了针对桌面端开发的Lepton 三件套(TinyLep、LepViewer、LepThumb)。那套工具帮我高效存档了250GB照片,且有着极佳的使用体验。
但随着我这几天的使用,新的需求出现了:如果我想要在在线相册里查看我的照片,浏览器是不认识Lep格式文件的啊,如何在浏览器里在线查看Lep文件呢?为了填补这个空白,我开发了 Lepton 家族的第四个成员:**Lepton WASM**。
为什么需要 Lepton WASM?
在 Web 环境下处理 .lep 文件面临两个核心挑战:
- 兼容性:由于
.lep并不是通用格式,浏览器无法查看Lep文件 - 性能:Lepton 这种针对 DCT 系数重组的算法,计算量远大于普通压缩。如果用纯 JavaScript 编写解码器,速度会慢到令人绝望。
得益于 Rust 优秀的生态,我基于微软开源的 lepton_jpeg_rust 核心,利用 WebAssembly (WASM) 技术将其编译成了可在浏览器运行的二进制模块,该WASM文件完整版仅337KB,若只包括仅查看代码,WASM体积甚至可以精简到仅249KB,极其轻量还没我一张照片大
硬件加速:AVX To WASM SIMD
在桌面环境下,Lepton可以使用AVX2指令集提升速度,但在 WASM 环境下,我们无法直接操作 x86 的 256 位寄存器。
好在 WASM 标准已经引入了 SIMD (单指令多数据流) 支持。通过开启 simd128 特性,Lepton WASM 可以在浏览器中调用 CPU 的 128 位向量指令。实测开启 SIMD 后,**解码速度提升了约 25%**。这意味着在现代浏览器中,解码一张高清照片仅需不到一秒。
具体性能提升可以查看下表:
时间取三次的平均值,图片大小为1.45MB
| 压缩(SIMD 加速) | 解压(SIMD 加速) | 压缩(兼容版) | 解压(兼容版) | |
|---|---|---|---|---|
| 平均时间 | 431 ms | 421 ms | 597 ms | 577 ms |
| 第一次耗时 | 438 ms | 410 ms | 596 ms | 589 ms |
| 第二次耗时 | 423 ms | 437 ms | 599 ms | 555 ms |
| 第三次耗时 | 432 ms | 416 ms | 596 ms | 588 ms |
PS:尽管 WASM 让浏览器具备了近乎原生的计算能力,但 Web 环境由于其沙盒机制与单线程调度的特性,性能表现会很大程度上受到环境干扰。
- 资源竞争:解压过程属于计算密集型任务,如果此时浏览器正在进行复杂的 DOM 渲染或 CSS 动画,可能会产生调度冲突,导致耗时异常波动(极端情况下可能出现长达数秒的延迟)。
- 异步建议:为了避免阻塞 UI 交互,我强烈建议在 Web Worker 中运行编解码逻辑。这样即使是在进行高负载计算,页面依然可以保持丝滑滚动。
- 场景选型:Web 版的核心意义在于零依赖、即时预览、小规模快速处理,给跨平台查看兼容性做个兜底。如果你有数以万计的照片需要进行大规模批处理,桌面端的 TinyLep 具备无可比拟的性能优势。
极简的使用方法
为了兼顾不同的使用场景,我准备了两个版本的包:
- **Viewer (查看版)**:精简掉所有编码代码,体积极小。适合只需要在网页展示图片,不需要在线压缩的场景。
- **Full (全能版)**:包含完整的编解码能力。你可以直接用它做一个在线压缩工具,所有计算都在用户本地浏览器完成。
为了让展示 .lep 文件像展示原生图片一样简单,我利用 Web Components 封装了一个自定义标签 <lep-img>,无需进行复杂的配置,只需要引入JS,然后再使用自定义标签<lep-img>即可插入图片
<lep-img src="images/my_photo.lep"></lep-img>
目前大部分主流的浏览器都支持SIMD,本项目可以启用SIMD加速处理,这是目前的支持情况:
- Chrome ≥ 91 (2021年5月)
- Firefox ≥ 89 (2021年6月)
- Safari ≥ 16.4 (2023年3月)
- Node.js ≥ 16.4 (2021年6月)
为了照顾一些老版本浏览器,本项目分为SIMD加速版和兼容版,可以通过在JS里使用wasm-feature-detect这个项目检测浏览器是否支持SIMD,然后自动加载最优版本。
示例:
import { simd } from "https://unpkg.com/wasm-feature-detect?module";
simd().then(isSupported => {
if (isSupported) {
// 加载SIMD加速版
} else {
// 加载兼容版
}
});
你可以在控制台中输入以下JS代码查询浏览器是否支持SIMD:
import("https://unpkg.com/wasm-feature-detect?module").then(module => {
module.simd().then(isSupported => {
console.log(`SIMD: ${isSupported}`);
});
});
或者你也可以访问WebAssembly SIMD 检测查询自己的浏览器是否支持SIMD
你可以访问此Demo查看Lep在线查看效果:Lep在线查看示例
这里不对JS代码方面做过多介绍,感兴趣可以查看Demo实现
Lepton 工具全家桶
至此,Lepton的有关工具又新增了一个成员,现在不仅可以本地批量压缩、快速查看,还可以在浏览器中浏览了。
- **TinyLep**:负责大规模批量压缩,把硬盘里的 JPG 瘦身。
- **LepViewer**:负责本地电脑的即时预览。
- **LepThumb**:负责 Windows 资源管理器的缩略图显示。
- **LeptonWASM**:负责在网页端、H5、在线相册中原生支持预览和处理。
如果你也有在线查看Lep图片的需求,或者是单纯只想在线压个JPG试试水,欢迎尝试本项目。
- 项目地址:GitHub - LeptonWASM
- 在线演示:
阅读上一篇博文:Lepton 三件套
赞赏
如果这些工具帮到了你,或者为你节省了昂贵的对象存储(OSS/S3)费用,欢迎打赏支持:
门罗币钱包地址