在 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 場景的項目會在將來的一段時間內不斷的出現,你們能夠多多瞭解一下。