WebAssembly 加速执行
1. 简介
Webassembly 最早的目标是让代码在浏览器端更快地执行。WASM 将非 JavaScript 的语言(例如:C/C++,Rust,Golang等)的代码编译为低级字节码 Webassembly 模块(.wasm
文件),放入浏览器环境中,让浏览器直接执行这些模块。
WebAssembly 本质上是一种语言格式,它也是可人工编程的。它也有变量、函数、指令等基础概念。1
2
3
4
5(module
(type (;0;) (func (param i32)))
(type (;1;) (func))
(import "imports" "imported_func" (func (;0;) (type 0)))
)
2. 实际应用
Qt应用
Qt for WebAssembly 让 Qt 应用也能放到 Web 浏览器里使用。视频解码
当 FLV 格式的直播流到达前端时,需要对视频解码成 MP4 格式,再使用原生播放器播放。使用 JavaScript 转码效率较低,引入 Webassembly 替换 JavaScript 来进行转码后,播放视频的性能提高了将近 20%。图形渲染 Figma
使用 Webassembly 后,Figma 提高了Web端的响应和载入速度。
依托 Web 的快捷访问,Figma 打败了只有 mac 客户端的 Sketch。
3. Hello World
使用在线的编译器,将 add.c
文件转化为 add.wasm
1
2
3
4
float add(float a, float b) {
return a + b;
}
转换后的add.wasm
文件1
2
3
4
5
6
7(module
(type (;0;) (func (param f32 f32) (result f32)))
(func (;0;) (type 0) (param f32 f32) (result f32)
local.get 0
local.get 1
f32.add)
(export "add" (func 0)))
用 vscode 启动服务, .wasm
必须启动服务才能fetch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<head>
<meta charset="utf-8">
<title>WebAssembly Add example</title>
<style>
div {
font-size : 30px; text-align : center; color:blue;
}
</style>
</head>
<body>
<div id="textcontent"></div>
<script>
let sum;
fetch("add.wasm")
.then((response) => response.arrayBuffer())
.then((bytes) => WebAssembly.instantiate(bytes))
.then((results) => {
sum = results.instance.exports._Z3addff(13, 12);
console.log("The result of 13 + 12 = " +sum);
document.getElementById("textcontent").innerHTML = "The result of 13 + 12 = " +sum;
});
</script>
</body>
</html>
4. 应用
2.1 直播烟花特效
我们看直播时,经常可以看见由用户送礼触发的炫酷礼物特效,如嘉年华、烟花。实现方案一般有:
- MP4
在早期直播的礼物特效多以播放 MP4 为主。该方案的瓶颈很明显:难以支持交互类特效、受资源包体积约束无法做到大量排列组合的随机性特效。 - webgl渲染
相比于C++渲染,JavaScript 的低运行效率会严重影响渲染效果。将特效中重复且重 CPU 计算的逻辑转换为 WebAssembly 来调用是其中的重要优化之一。
1 | git clone https://github.com/AssemblyScript/assemblyscript.git |