🌞

WebAssembly基本介绍(老生常谈)

wasm 是一个可移植、体积小、加载快并且兼容 Web 的全新格式,由w3c制定出的新的规范是个啥wasm是一个二进制可执行文件,具有高性能、体积小的特点。可以在web端提高更快速的运算服务,本身不提

文链接在语雀:https://www.yuque.com/wumingshi/rkh1qq/

wasm 是一个可移植、体积小、加载快并且兼容 Web 的全新格式,由w3c制定出的新的规范

是个啥

wasm是一个二进制可执行文件,具有高性能、体积小的特点。可以在web端提高更快速的运算服务,本身不提供web持有的特性,也因此它先天不具备取代JS的作用,虽是web催生出的产物,却也可以运用于其他平台。

干个啥

  • 一句话,强计算,强资源类型的web应用都有发挥的空间,比如游戏、图片/视频编辑、AR/VR等
  • 除web外的服务端应用

当前主流的应用场景还是wasm辅助js完成页面任务,比如分担计算任务等,在数据可视化里,或许可以考虑其作为一个运算服务提供支持,减轻js的线程压力.

支持度

主流浏览器已经全部支持

image.png

真爱生命,远离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的传统编译和使用方法,当前有其他更容易使用的方案

Go的起步较晚,目前C++和Rust比较成熟,其中Rust社区最为火热,也有wams-pack解决方案,为js提供模块包提供便利。


这么牛,为啥还不爆炸

  • 无强场景:web本身强运算场景较少,运算压力一般不会压在web侧,没有强需求场景,减小体积也不是现在4g/wifi场景下的迫切追求,在轻量的运算中,运算速度的优势并不明显
  • 上手路线较陡,需要相对底层的语言进行支持,C++/Rust上手难度都相对较高。拿Rust => wsm而言,目前都还是试用阶段,wasm还有很多好的特性未支持完成,例如多线程等,rust学习难度相对比较大,很多特点很有创新性.
  • js太威武...

体验

写在最后

看完之后,在数据可视化中wasm能干些什么呢?在强运算场景下,wasm或许可以作为一个工具集提供服务,进而提升页面性能。

updatedupdated2023-10-312023-10-31