在 2019 年 12 月以前,若是你要编写一个web页面,那必定离不开 html、css、js 这三个好兄弟。在 2019 年 12 月以后 W3C 宣布 webassembly 加入了他们。为何要在三兄弟后加入 webassembly ?它和以前的有什么区别么?以 js 为对比,咱们具体看一下它们的区别。css
js 是一种解释型语言,它代码运行以前不会进行编译工做,而是在执行的过程当中实时编译。为了让边编译边执行可以顺利进行,咱们拥有了 js 引擎。html
wasm 则与之不一样,它自己不是一种编程语言,而是一种字节码的标准,能够经过不一样种类的高级编程语言,好比 Rust、Go、Python 等等,经过各自编译器将代码转换成 .wasm 文件,放入到浏览器预先作好的 wasm 虚拟机当中运行。vue
同时这种与 js 不一样,能够预先运行的特点,也给 wasm 带来了一些优点:react
固然若是只是这么说,咱们并不能很直观的感觉出这些优点究竟有多大,恰好目前浏览器已经支持了以 wasm 规范的虚拟机。git
接下来,咱们经过一个 Chrome 与 Safari 的实例测试,来感觉一下。github
首先咱们用原生的 js 写一段 fib 代码测试时间,代码内容以下:web
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> function fibonacci(n) { if (n == 0 || n == 1) return n; return fibonacci(n - 1) + fibonacci(n - 2); } function fibonacciTime() { console.time("js") fibonacci(40) console.timeEnd("js") } fibonacciTime() </script> </body> </html>
用 live-server 测试时间,用时 1275 毫秒到 1329 毫秒。算法
而后咱们用 Rust 转义成 wasm 再次测试。特别须要注意的是,测试用到的算法都是最普通的递归迭代,在实际使用中咱们还可使用动态规划来再次优化。typescript
言归正传,而后咱们用 rust-wasm 编译器将用 rust 写好的 fib 代码转换成 wasm 文件。express
下载 wasm 编译器:
curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
配置 Cargo.toml:
[package] name = "wasm" version = "0.2.0" authors = ["hzjsea"] edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [lib] crate-type = ["cdylib"] path = "src/main.rs" [dependencies] wasm-bindgen = "0.2.48" chrono = "0.4.19"
main.rs:
use chrono::Utc; use wasm_bindgen::prelude::*; use std::time::Instant; #[wasm_bindgen] pub fn fib(n: i32) -> i32 { match n { 0 => 1, 1 => 1, _ => fib(n - 1) + fib(n - 2), } } pub fn main(){ let result = fib(40); println!("{:?}", result); }
挂载wasm文件,即相似 vue,使用 index.html 把 wasm.js 文件挂载起来:
<script type="module"> main() async function main() { const wasm = await import('/pkg/wasm.js') await wasm.default('/pkg/wasm_bg.wasm') console.time("rust") console.log(wasm.fib(40)) console.timeEnd("rust") } function fibonacci(n) { if(n==0 || n == 1) return n; return fibonacci(n-1) + fibonacci(n-2); } function fibonacciTime(){ console.time("js") fibonacci(40) console.timeEnd("js") } fibonacciTime() </script>
以后用编译器编译 Rust 代码生成 .wasm 文件:
wasm-pack build --target web --no-typescript --mode normal
而后咱们能够明显看到,在相同的 live-server 测试下时间相差一倍左右。
由于这次编译指定不生成 wasm 的 ts 版本。全部只有上面的几个文件,其中:
{ "name": "wasm", "collaborators": [ "hzjsea" ], "version": "0.2.0", "files": [ "wasm_bg.wasm", "wasm.js" ], "module": "wasm.js", "sideEffects": false }
指定打包的各种属性
wasm.js转义后的二进制文件
由rust代码转移过来的wasm.js文件。
看完了实例测试,咱们不能略过测试中提到的 Rust。Rust 中有个相似于 react 的框架,叫作Yew。关于 Yew 官方[https://github.com/yewstack/y...
Yew is a modern Rust framework for creating multi-threaded front-end web apps with WebAssembly.
大体看完了 Rust,若是你还想看更多的 WebAssembly 流程,官方提供的一个计时器的练手项目能够知足你的需求
项目地址 https://yew.rs/docs/zh-CN/get...
主要能够看下 lib.rs 这个文件
虽然 webassembly 做为一种新的 web 技术经常被提起,可是由于其工具链的调试困难,包体积过大等等问题还在解决的过程当中,同时也代表了 wasm 并不可能在短期内直接代替 js,他们之间更多的是一种互补合做的关系。但不能否认的是,适合 webassembly 场景的项目会在将来的一段时间内不断的出现,你们能够多多了解一下。