浅谈WebAssembly

Posted 前端知知

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浅谈WebAssembly相关的知识,希望对你有一定的参考价值。

前言

1.定义

WebAssembly 是一个可移植、体积小、加载快并且兼容 Web 的全新二进制格式;可以通过C/C++/Rust等静态语言编译生成,后缀名为.wasm;可以通过Web API在浏览器中加载、解析和运行。通过定义我们了解一下内容:

  • WebAssembly文件格式:二进制;
  • 如何生成的:由其他语言编译而成;
  • 运行在哪里:通过Web API 加载,运行在浏览器中

以下是一个 .wasm 的文本格式,可以整体感知一下:

(module
  (type $t0 (func))
  (type $t1 (func (param i32 i32) (result i32)))
  (func $__wasm_call_ctors (type $t0)
    nop)
  (func $addTwo (type $t1) (param $p0 i32) (param $p1 i32) (result i32)
    local.get $p0
    local.get $p1
    i32.add)
  (global $__dso_handle i32 (i32.const 0))
  (export "__wasm_call_ctors" (func $__wasm_call_ctors))
  (export "addTwo" (func $addTwo))
  (export "__dso_handle" (global 0))
  (export "__wasm_apply_data_relocs" (func $__wasm_call_ctors)))

2.实际例子

2.1 使用其他语言定义一个函数


我们使用C 语言定义一个简单的add.c 文件计算两数之和

//add.c
#include <stdio.h>

int addTwo(int a, int b) { 
  return a + b;
}

2.2 转换成 WebAssembly 文件


不同的语言转换成 WebAssembly 文件所需编译器不同,我们以C/C++为例,其使用的是emscripten, 可去github上下载和安装

# 下载地址
git clone https://github.com/juj/emsdk.git

#安装
cd emsdk
./emsdk install latest
./emsdk activate latest

#让环境生效
source ./emsdk_env.sh

#确认是否安装成功
emcc --version

接着使用 emcc 转换文件

emcc add.c -O3 -s WASM=1 -s SIDE_MODULE=1 -s EXPORTED_FUNCTIONS='["addTwo"]' -o add.wasm

也可以使用WasmFiddle(https://wasdk.github.io/WasmFiddle/)在线转换。

2.3 加载与运行

现在浏览器还不支持使用类似js文件的加载方式进行.wasm 文件加载。可以使用XHR 或Fetch

fetch('./add.wasm')
.then(res => {return res.arrayBuffer()})
.then(WebAssembly.instantiate) 
.then(module => { 
  console.log(module);
  const sum = module.instance.exports.addTwo(1, 2);
  console.log(sum)
}) 

3.性能对比

我们使用 js 调用和使用 WebAssembly方式调用递归方式实现斐波那契数列函数对比。先简单回顾下斐波那契数列函数

function Fibonacci(n){
 return n <= 1 ? 1 : Fibonacci(n - 1) + Fibonacci(n - 2);
}

同样我们使用C语言实现然后生成fib.wasm,测试两种不同方式结果如下:

我们可以看出复杂的运算或者处理,用WebAssembley更合适。

4.应用场景

WebAssembly 的出现,并不是为了取代javascript。其主要有两个作用:

  • 使用其他语言已经实现但JavaScript并未实现能力,比如OpenGL 是C++语言实现的,如果想在浏览器中使用其提供的方法,那么则可以使用OpenGL 提供的.wasm 文件;
  • 做JavaScript不擅长的工作。比如绘图,编码,解码,数学计算等,都可以在 wasm 中实现,然后 js 就可以使用wasm所提供的能力。

现在已经有线上项目比如视频剪辑、游戏、md5计算等相关应用在线上使用,一个实际的例子,VE云剪辑就是 Worker + WebAssembly的应用。

5.最后

本文简述WebAssembly的定义,使用和性能,因为业务场景有限,笔者还并未用在实际项目中,如果你已经在使用了,欢迎留言沟通交流呀。最后打一个小广告,笔者所在公司腾讯开始进行提前批招聘啦,如果有兴趣,可以通过二维码投递哟 ^_^

参考资料

[1]官网: https://webassembly.org/

[2]应用场景: https://www.techug.com/post/webassembly-application-example.html

[3]WebAssembly 在 Web 端视频的应用: https://segmentfault.com/a/1190000038330781

[4]md5实践: https://juejin.cn/post/6931155704594038792

以上是关于浅谈WebAssembly的主要内容,如果未能解决你的问题,请参考以下文章

浅谈Mybatis

浅谈AngularJS中的$parse和$eval

将现有 C# 代码编译为 WebAssembly

《WebAssembly 权威指南》在浏览器中运行遗留代码

Gopher 的 WebAssembly 实践

如何将C ++ 11代码编译为webassembly?