Coding . . .
首页
/
Blog List
/
正文
Blog List
其他格式图片转web
Author: Tool.butof.com
2024-04-16

大约在2022年的时候,当时那个公司,因为祖传代码的因素,大约3G+的静态资源全都放到了项目里,导致每次上线发版时,打包docker的时间比较长, 于是,决定一次性把图片,视频什么的静态资源全转到s3上,然后因为当时的图片资源基本都是2M-12M的Jpg图,网站加载速度也不快,想着顺便把图片都转成webp, webp格式的兼容性比较好,同时压缩比又很高,也比较保证清晰度。

当时找了一些在线的转webp的工具,也许我找的不够全吧,能用的基本都限制体积,有的不能超5M有的不能超过10M,要么限制数量,每次只能转20张,但是我们有上千张啊, 每都只传20张,那不是太慢了?于是就想自己搞了一个工具,自己开发,不限制体积,不限制数量。

就在当时,为了体验tauri,于是就用react+rust写了一个工具,大约花了3天时间写完了demo,然后电脑8核16G,开8个线程,平均10M图片转一个webp需要1-3秒就完成了, 如果按1000张算的话,基本上5分钟以内就全完事了。

是的,为了一口醋,包顿饺子。其实还好了,1000张/20 = 500次,我如果用在线的工具,要传500次,太可怕了。

然后当时把工具开发完了之后,时间就到了2024年,我其实是想把这个工具放到线上,解决之前我遇到的痛点,不限制体积,不限制数量,同时又兼顾rust转码时的高性能, 但是问题来了,如果走服务器,如果每个人同时转码100张图片,需要100秒,那么其他用户再同时转码100张,不说多人,就说同时2个人用,这就200张,按照一张一秒的速度,还得200秒, 那么这个就不好办了,当时想了如下两种方案:

  • 一个人全部转码完成后,再转另一个人的
  • 饭店策略,即,先给一个人转10张,再转另一个人的5张,然后再转第三个人的2张,以此类推
  • 但是是终我全放弃了,我忽略了一个事,就是我那可怜的带宽+可怜的cpu核数,就算只有一个人用,100张,每张10M,上传就得2560秒,42分钟,简直是太可怕了。果断放弃。

    于是,我决定做纯网页版的转webp的版本,可以说这个小工具花费时间是现有几个工具里最长的了,折腾了好多个技术栈。因为rust转码很快,我就想把rust版转成wasm, 然后利用wasm的加速来实现网页里的提速,然后问题一个接着一个的来了

  • rust转webp的crate(可以理解成一个插件)所调用的C,并不支持交叉编译成wasm
  • 找了不少github上的golang版的转码也是调用的C,也是如此
  • 只好找到谷歌最原始的libwebp C库,然后使用emsdk来查资源,写映射,折腾了好几天,终于把webp编码功能做成wasm了
  • 这样好了,wasm也有了,测试呗,发现,wasm版的webp转码速度比纯rust或纯c的版本,慢了8-10倍,以我电脑为例,rust需要1秒,wasm需要8秒,可怕不可怕?
  • 8秒一个图片也不行啊,就算纯网站端,图片读取时间是快了,但是转码要8秒是无法接受的
  • 算了,还是回到js领域吧,用canvas转webp,最终也确实使用了这个技术方案,转码速度比wasm快一倍吧,即rust本机 1秒,wasm 8秒,js canvas 4秒, 行了,上线

    从这个事件开始,我不像之样迷恋wasm了,也许因为浏览器的一些限制,限制了wasm的性能。不过,话说回来,js里canvas的转码功能也并不是js,也是调用浏览器里原生功能,而且也是经过高度优化的。所以性能会好一些

    好了,一波多折,折腾来折腾去,webp转码工具搞完了,不限制尺寸,不限制数量,转码速度还不错,支持多个worker复用式并行计算,还不用上传到服务器,保护了用户的隐私。

    这个功能最好还是在电脑上使用,手机端,尤其是低版本iphone ios,支持度比较弱。

    最后如果你也想体验一下,直接点击传送门按钮