webAssembly简介
Posted 前端配送站
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了webAssembly简介相关的知识,希望对你有一定的参考价值。
序
在前端领域还处于战火纷飞却又百家争鸣的年代,相关的技术风起云涌,各成一派,类似我这样的看客,在经历着这些知识的洗礼之时,不免想搬一下砖,所以就有了这篇介绍webAssembly的文章。
1 起因
针对js语言自身的原因(语法灵活,性能),近来出现了一些js的变种,例如:ts、asm等,但是这些变种也都有自己的缺陷(eg:ts只解决语法灵活,并未对性能做优化),这个时候就一种发声,那就是webAssembly,它主张创造一种新的字节码格式。
2 经过
2.1 overview
WebAssembly (abbreviated Wasm) is a binary instruction format for a stack-based virtual machine. Wasm is designed as a portable target for compilation of high-level languages like C/C++/Rust, enabling deployment on the web for client and server applications.
相对于 JS,WebAssembly 有如下优点:
体积小:由于浏览器运行时只加载编译成的字节码,一样的逻辑比用字符串描述的 JS 文件体积要小很多;
加载快:由于文件体积小,再加上无需解释执行,WebAssembly 能更快的加载并实例化,减少运行前的等待时间;
兼容性问题少:WebAssembly 是非常底层的字节码规范,制订好后很少变动,就算以后发生变化,也只需在从高级语言编译成字节码过程中做兼容。可能出现兼容性问题的地方在于 JS 和 WebAssembly 桥接的 JS 接口。
快速体验:在控制台输入以下代码就可体验
WebAssembly.compile(new Uint8Array(`
00 61 73 6d 01 00 00 00 01 0c 02 60 02 7f 7f 01
7f 60 01 7f 01 7f 03 03 02 00 01 07 10 02 03 61
64 64 00 00 06 73 71 75 61 72 65 00 01 0a 13 02
08 00 20 00 20 01 6a 0f 0b 08 00 20 00 20 00 6c
0f 0b`.trim().split(/[\s\r\n]+/g).map(str => parseInt(str, 16))
)).then(module => {
const instance = new WebAssembly.Instance(module)
//使用 WebAssembly.Instance 将模块对象转成 WebAssembly 实例
const { add, square } = instance.exports
//通过 instance.exports 可以拿到 wasm 代码输出的接口
console.log('2 + 4 =', add(2, 4))
console.log('3^2 =', square(3))
console.log('(2 + 5)^2 =', square(add(2 + 5)))
})
ps:官网上说火狐、IE、Safari、chrome这四个浏览器已经支持webassembly1.0
Chrome:
打开chrome://flags/#enable-webassembly,选择enable。
2.2 hello world
1 .wasm文件长啥样?
sample.wasm
0061 736d 0100 0000 0107 0160 027f 7f01
7f03 0201 0007 0701 0361 6464 0000 0a09
0107 0020 0020 016a 0b
2 全是二进制码,看不懂怎么办?
wabt工具!
https://github.com/webassembly/wabt该工具可以把wasm文件和wat文件相互转换
按照步骤各种装完之后(long time…),执行命令
$wasm2wat sample.wasm -o sample.wat
.wat文件长啥样?
sample.wat
(module
(func $add (param $lhs i32) (param $rhs i32) (result i32)
get_local $lhs
get_local $rhs
i32.add)
(export "add" (func $add))
)
3 如何在js中使用?
大致逻辑:
For basic loading, there are three steps:
Get the .wasm bytes into a typed array or ArrayBuffer
Compile the bytes into a WebAssembly.Module
Instantiate the WebAssembly.Module with imports to get the callable exports
具体实现:
WebAssembly.instantiateStreaming(fetch('sample.wasm'))
.then(obj => {
console.log(obj.instance.exports.add(1, 2)); // "3"
});
4:webAssembly也支持模块化的导入导出
module.wat
(module
(func $i (import "imports" "imported_func") (param i32))
(func (export "exported_func")
i32.const 42
call $i))
js
var importObject = {
imports: {
imported_func: function(arg) {
console.log(arg);
}
}
};
fetch('simple.wasm').then(response =>
response.arrayBuffer()
).then(bytes =>
WebAssembly.instantiate(bytes, importObject)
).then(result =>
result.instance.exports.exported_func()
);
5 WebAssembly的底层内存模型、WebAssembly.Table()等等
2.3 用什么编写webAssembly?+怎样生成.wasm文件?
首先呢?用什么语言coding?在对webAssembly进行介绍的时候引用了一段官网的话,其实人家对自己产品的定位是很高的呢
Wasm is designed as a portable target for compilation of high-level languages like C/C++/Rust, enabling deployment on the web for client and server applications.
下面就简单介绍一下用ts和C/C++编写代码,生成.wasm文件的过程
2.3.1 ts -> wasm
安装:
https://github.com/AssemblyScript/assemblyscript#installation
用 TypeScript 实现斐波那契序列计算的模块如下: f.ts
export function f(x: i32): i32 {
if (x === 1 || x === 2) {
return 1;
}
return f(x - 1) + f(x - 2)
}
run: asc f.ts -o f.wasm //把代码编译成可运行的WebAssembly 模块
js加载调用:
fetch('f.wasm') // 网络加载 f.wasm 文件
.then(res => res.arrayBuffer()) // 转成 ArrayBuffer
.then(WebAssembly.instantiate) // 编译为当前 CPU 架构的机器码 + 实例化
.then(mod => { // 调用模块实例上的 f 函数计算
console.log(mod.instance.f(50));
});
2.3.2 c/c++ -> wasm
安装:https://github.com/juj/emsdk
hello.c
#include <stdio.h>
int main(int argc, char ** argv) {
printf("Hello World\n");
return 0;
}
emcc hello.c -s WASM=1 -o hello.html
ps:编译后会自动有一个hello.js
2.4 扩展
可接入webpack
WebAssembly调JS
直接执行wasm二进制文件
3 结果
目前WebAssembly的发展尚不成熟,但是它有自身的一些优势,能够解决一些性能问题,所以也有自己的立足之地。
WebAssembly 更适合用于写模块,承接各种复杂的计算,如图像处理、3D运算、语音识别、视音频编码解码这种工作,主体程序还是要用 javascript 来写的。。
本文参考:
WebAssembly 现状与实战
https://www.ibm.com/developerworks/cn/web/wa-lo-webassembly-status-and-reality/index.html
MDN
https://developer.mozilla.org/zh-CN/docs/WebAssembly/Using_the_JavaScript_API
webassembly官网
https://webassembly.org/getting-started/developers-guide/
WebAssembly详解及其使用案例https://cloud.tencent.com/developer/article/1089927
以上是关于webAssembly简介的主要内容,如果未能解决你的问题,请参考以下文章
Docker 学习总结(78)—— WebAssembly 入门简介
Docker 学习总结(78)—— WebAssembly 入门简介