wasm 是一个可移植、体积小、加载快并且兼容 Web 的全新格式,由w3c制定出的新的规范
是个啥
wasm是一个二进制可执行文件,具有高性能、体积小的特点。可以在web端提高更快速的运算服务,本身不提供web持有的特性,也因此它先天不具备取代JS的作用,虽是web催生出的产物,却也可以运用于其他平台。
干个啥
- 一句话,强计算,强资源类型的web应用都有发挥的空间,比如游戏、图片/视频编辑、AR/VR等
- 除web外的服务端应用
当前主流的应用场景还是wasm辅助js完成页面任务,比如分担计算任务等,在数据可视化里,或许可以考虑其作为一个运算服务提供支持,减轻js的线程压力.
支持度
主流浏览器已经全部支持
真爱生命,远离IE,连Edge都看不上它,
除了在浏览器里利用js调用,也可以在其他语言中运行,当前也有一些拓展进行支持,例如php(https://github.com/wasmerio/php-ext-wasm)、Python(https://github.com/wasmerio/python-ext-wasm)等
怎么用
在浏览器的global中有一个WebAssembly
是在JS执行wasm的主要集成,它是一个类似JSON挂载在global上的对象.
如下是一个简单was格式,也就是wasm的文本格式,可以通过wabt编译成wasm,编写wasm也可以不通过这种语义,当前也有其他语言直接编译成wasm,例如rust、go等。
(module (import "js" "import1" (func $i1)) // 从js环境中导入的方法 (import "js" "import2" (func $i2)) (func $main (call $i1)) (start $main) (func (export "f") (call $i2)) // 将自己内部的方法导出,提供给js )
以下是在js中引用上述wasm模块的方法,参考注释
// importObj是将js对象赋给wasm调用 var importObj = {js: { import1: () => console.log("hello,"), import2: () => console.log("world!") }}; fetch('demo.wasm').then(response => response.arrayBuffer() // wasm的内存buffer ).then(buffer => /** * 实例化,返回一个实例WASM.module和一个WASM.instance, * module是一个无状态的 带有Ast.module 占位的对象; * 其中instance就是将module和ES相关标准融合,可以最终在JS环境中调用导出的方法 */ WebAssembly.instantiate(buffer, importObj) ).then(({module, instance}) => instance.exports.f() // 执行wasm中的方法f );
以上是wasm的传统编译和使用方法,当前有其他更容易使用的方案
- C++编译成wasm,Emscripten
- Rust编译成wasm,wasm-bidgen
- Go编译成wasm,https://github.com/golang/go/wiki/WebAssembly
- ....
Go的起步较晚,目前C++和Rust比较成熟,其中Rust社区最为火热,也有wams-pack解决方案,为js提供模块包提供便利。
这么牛,为啥还不爆炸
- 无强场景:web本身强运算场景较少,运算压力一般不会压在web侧,没有强需求场景,减小体积也不是现在4g/wifi场景下的迫切追求,在轻量的运算中,运算速度的优势并不明显
- 上手路线较陡,需要相对底层的语言进行支持,C++/Rust上手难度都相对较高。拿Rust => wsm而言,目前都还是试用阶段,wasm还有很多好的特性未支持完成,例如多线程等,rust学习难度相对比较大,很多特点很有创新性.
- js太威武...
体验
写在最后
看完之后,在数据可视化中wasm能干些什么呢?在强运算场景下,wasm或许可以作为一个工具集提供服务,进而提升页面性能。