WebAssembly
是一种运行在现代网络浏览器中的新型代码,并且提供新的性能特性和效果。它设计的目的不是为了手写代码而是为诸如C、C++和Rust等低级源语言提供一个高效的编译目标。什么是编译目标?当我们写 TypeScript 的时候,Webpack 最后打包生成的 JavaScript 文件就是编译目标。也就是说,你不需要直接写 WebAssembly 代码,而是从其他高级语言编译过来就行。
- 快速、高效
WebAssembly 的二进制文件比 JavaScript 文本文件小得多,因而下载速度更快。其解析和执行速度也更快。对比 JavaScript,JavaScript 是一种动态类型语言,不必事先定义变量类型,也不需要提前编译。这使得代码编写变得简单快捷,但这也意味着 JavaScript 引擎有大量的额外工作。 JavaScript 引擎在运行 JavaScript 代码的时候,必须解析,编译并优化代码。而 WebAssembly 本身就以二进制形式提供,解析速度更快,且它是静态类型的,其引擎在编译期间不需要类型推断,也没有垃圾收集等。WebAssembly代码在不同平台上能够以接近本地速度运行。
js 和 webassembly 的执行过程对比: WebAssembly 执行快更详细的原因可以看这里
- 可移植、灵活
使用 WebAssembly ,只需要一次编译,您的应用程序将可以在每个现代浏览器中运行。使用“原生”模块也就没那么复杂,如果开发人员可以跨不同平台 (例如,在 Web 和桌面应用程序) 共享同一脚本语言或低级语言代码库,则可以节省开发时间并降低维护成本。而WebAssembly 为你提供了一种在不降低这些平台性能的前提下实现此目标的方法。
- 安全
WebAssembly 默认为你提供轻量级沙箱,像其他网络代码一样,它遵循浏览器的同源策略和授权策略。
- webp图片的优势在于它具有更优的图像数据压缩算法,在拥有肉眼无法识别差异的图像质量前提下,带来更小的图片体积。但是在支持性上,如图: ios 系统只有版本在14以上才支持,安卓基本都支持。因此,我们想用它的时候,只能采取降级方案。那么有没有办法在系统不支持webp的情况下渲染webp图片呢
- 视频上传&视频编辑
- 封面出来慢,且非标准视频截不出图片
- 视频上传慢(视频压缩)
- 非视频文件或无法解码的文件需要上传后台后才知道(视频转码/解码)
- 云原生 WebAssembly 发展和应用
可基于 WebAssembly 支持 webp 格式的图片渲染,且实现方案比较成熟。
- 微信官方小程序在基础库版本大于 2.9.0 时已支持 webp 格式的图片渲染。不过官方不是基于 WebAssembly 的。
虽然WebAssembly的解码性能比JavaScript快不少,但遇到超大分辨率(如1920 x 1080等)的webP时,却远远落后于客户端的解码性能。综合对比各种方案的性能和兼容性之后,而是采用了基于iOS客户端自定义协议webphttps的方案,大致步骤如下:
- 首先,微信小程序基础库判断开发者在image组件使用的是webP格式时,则在image src里加上webp头部如:webphttps://example.png。
- 然后,客户端通过NSURLProtocol协议挟持webphttps的请求,并下载相应的webP数据进行解码。
- 最后,再把解码后的image数据回吐给浏览器进行渲染显示。
基于 WebAssembly 的实现原理可参考这里
- 电脑端打开小程序,暂不支持 webp 格式的图片渲染(电脑端打开,本身网络环境相对更好。或推动客户端支持)
- 对于h5页面,也有比较成熟的基于 WebAssembly 支持 webp 格式的图片渲染的方案,参考这里
主要凭借 FFmpeg 的 WebAssembly 在前端实现视频截帧/转码/压缩等。
- 视频截帧已经转为 wasm 版的现成的库:https://github.com/jordiwang/web-capture,试用了一下,截图非常快。
如 在
2.3G
大的视频下,截取第5453
帧,只需要273ms
: 但是存在一点问题:
- 该库定义的“帧”粒度不够细,两个“帧”之间会有较大的距离,会有部分视频帧无法截取。(可自己手动调整一下截帧规则,然后重新打包一个wasm版的 ffmpeg)
- 该包只实现了截帧
- 也可以用 ImageMagick 转为wasm版,然后实现图片格式转换
- 可基于 FFmpeg 实现图片合成视频、音频视频合成、视频文字编辑等
这块可以自己再摸索的点有:
- 截帧优选(结合tensorflow截多张图给用户选择)
- 处理文件数据大占用内存问题
- 本地媒体元素(图片、音频、文字等)合成视频及视频编辑
- 视频/图片转码
WebAssembly 是一个轻量级、快速、安全和多语言的函数“容器”。WebAssembly 将由 Kubernetes 和 Docker 开拓的云原生编程模式,从大型数据中心引入边缘计算和微服务领域。
Wasm 可以作为云原生应用程序的通用 runtime。与类似 Docker 的应用程序容器相比,WebAssembly runtime 以更低的资源消耗实现更高的性能。云中 WebAssembly 的常见用例包括以下内容:
- 用于 serverless 函数即服务 (FaaS) 的 runtime,https://github.com/second-state/aws-lambda-wasm-runtime
- 将用户定义的函数嵌入到 SaaS 应用或数据库,http://reactor.secondstate.info/en/docs/
- 用于 service mesh sidecar 应用的 runtime
- WasmEdge WebAssembly runtime,支持在 WebAssembly runtime 中从 JavaScript 调用 C/C++ 或 Rust 函数,充分利用 WebAssembly 的计算效率。
更多可以了解这个:https://www.zhihu.com/column/c_1311629555841826816
其实基本不会自己动手写,而是把一些低级语言的好用的库编译过来用或用低级语言编写好对应的库再编译过来,生成对应的 .wasm
文件
由于我这次主要是调研性质,所以主要是想看有哪些低级语言的库,可以更好地被用进来。我没有从头开始编译,直接找了编译好的库来测试。如果自己想体验一把的话,可以按照这里的方法进行:
Chrome 91默认开启了WebAssembly SIMD(https://www.chromestatus.com/feature/6533147810332672)。SIMD是一种特殊的CPU指令,它可以实现数据层面的并行处理。SIMD常用于视频、音频、图像、加密、动画、游戏、AI等需要处理大量数据的应用场景,可以极大地提高向量类型的数据处理性能。在手势识别应用中,WebAssembly SIMD可以明显提高性能,使用SIMD和不使用SIMD的差距非常明显(两者都可以直接进行测试),使用SIMD时帧率更高,画面更加流畅。
详见:https://zhuanlan.zhihu.com/p/375356675
- https://developer.mozilla.org/zh-CN/docs/WebAssembly/Concepts
- webassembly基础与应用
- https://www.infoq.cn/article/lwlcldgjyc7lye95ewl8
- https://zhuanlan.zhihu.com/p/42718990
- https://zhuanlan.zhihu.com/p/411017703
- https://zhuanlan.zhihu.com/p/375356675
- 欢迎加我微信(winty230),拉你进技术群,长期交流学习...
- 欢迎关注「前端Q」,认真学前端,做个有专业的技术人...