跳到主要内容
CNode

在 Next.js 中用 WASM 做纯浏览器 GIF 压缩:批处理与目标体积重试

分享
Ggifcompressor发布于 2 小时前
0270

先说明关系:我是 GIF Compressor 的开发者。这篇分享主要讲实现中的几个取舍,项目链接放在文末。

做这个工具时,我希望用户压缩动图不必先把原文件上传到服务器。前端用 Next.js 15 和 React,压缩则交给 gifsicle-wasm-browser。页面是客户端组件,用户点“压缩”后才动态加载 WASM 依赖;文件通过浏览器的 File 对象传入,结果转成 Blob 并用对象 URL 预览、下载。

核心调用大致如下(省略错误处理和结果类型转换):

const gifsicle = (await import('gifsicle-wasm-browser')).default;

const result = await gifsicle.run({
  input: [{ file, name: 'input.gif' }],
  command: ['-O2 --lossy=60 --colors=128 input.gif -o /out/output.gif'],
  isStrict: true,
});

这里有几个实际踩到的点:

  1. 不要把压缩参数当成一个“质量百分比”。 GIF 文件大小同时受画面尺寸、调色板颜色数、帧内容和压缩强度影响。我做了“画质优先、均衡、文件最小”三档预设,并保留高级参数供手动调整。强压缩可能出现色带或噪点,所以结果需要预览。
  2. 批量处理要考虑浏览器内存。 界面一次最多接收 20 个 GIF,每个文件上限 100 MB;代码逐个处理待压缩文件,完成一个就保存结果状态。原图和输出图的对象 URL 在移除文件或组件卸载时会释放,避免浏览器长时间持有预览资源。
  3. 目标体积是“尝试”,不是保证。 针对 1 MB 和 10 MB 限制,程序会按顺序尝试更强的颜色、尺寸和压缩配置;如果仍未达标,就明确显示“高于目标”,而不是假装成功。源文件本身也不会被覆盖。

目前所有 GIF 压缩都在浏览器内完成,没有把文件送到远端压缩服务。这个方案省掉服务器上的转码任务,但大文件处理速度取决于用户设备,画质与体积之间也没有万能参数。

项目地址:GIF Compressor。如果你也在 Next.js 项目中集成 WASM 媒体处理,欢迎交流内存管理和批量任务的做法。

查看回复

回复 (0)

暂无回复,成为第一个参与讨论的人。

参与回复

登录后即可参与回复。登录