webassembly的作用
-
wasm: 一種體積小、加載快並且可以在Web瀏覽器端運行的底層二進制數據格式,並且可以由C++等語言轉化而來
-
webassembly的操作接口:例如WebAssembly.instantiate就可以將一份wasm文件編譯輸出為JS能夠直接調用的模塊對象
webassembly項目的編碼流程
-
性能無強關的部分用JS編寫
-
性能強相關的,並且需要大量本地運算的部分,先用C++/Rust編寫,通過命令行工具轉化為wasm代碼后讓JS調用

玄學的webassembly性能提升
當您使用WebAssembly時,不要總是期望得到20倍的加速。您可能只得到2倍的加速或者20%的加速。或者,如果您在內存中加載非常大的文件時,或者需要在WebAssembly和JavaScript之間進行大量通信時,那么速度可能會變慢。 作者:Robert 《Level Up With WebAssembly》一書的作者,同時也是一位生物信息學軟件工程師
在上面的文章的作者Robert,做了這樣一個實驗,他使用 seqtk,一個用C編寫的評估DNA測序數據質量(通常用於操作這些數據文件)的軟件,去對比webassembly相對於普通JS帶來的性能提升
-
第一步:運行序列分析軟件seqtk,對比性能:9倍提升
-
第二步:刪除不必要的printf輸出,對比性能:13倍提升
-
第三步:去除函數的重復調用后,對比性能:21倍提升


文章鏈接 作者:detectiveHLH
-
對於長文本(2M文本) 的密集計算,webassembly的性能提升很大
-
對於短文本("IVWEB")的密集計算,webassembly和純JS性能相差無幾


webassembly的兼容

實戰 WebAssembly
-
編寫Rust代碼,然后通過wasm-pack轉化成wasm代碼
-
編寫C/C++代碼,然后通過Emscripten轉化成wasm代碼
備注:Rust是一門高性能的系統編程語言
通過Rust接入WebAssembly
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
2.安裝編譯工具wasm-pack(相當於前端的babel)
cargo install wasm-pack
cargo new --lib hello-wasm
初始化的文件夾如下所示

extern crate wasm_bindgen; use wasm_bindgen::prelude::*; #[wasm_bindgen] pub fn is_odd(n: u32) -> bool { n % 2 == 1 }
5.修改配置文件Cargo.toml
[package] name = "hello-wasm" version = "0.1.0" authors = ["作者名"] edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [lib] crate-type = ["cdylib"] [dependencies] wasm-bindgen = "0.2"
-
dependencies中必須要有wasm-bindgen這個依賴
-
同時還要指定crate-type = ["cdylib"],否則轉化不能成功
wasm-pack build --scope [自己的名字] // My Example wasm-pack build --scope penghuwan
編譯開始



1.cd pkg
2.npm publish --access=public
const js = require("hello-wasm"); js.then(js => { const num1 = js.is_odd(3); const num2 = js.is_odd(4); console.log(num1); console.log(num2); });
9.瀏覽器輸出

通過C/C++接入WebAssembly
備注:如果沒有將source ./emsdk_env.sh寫入到啟動文件中的話,那么每次使用前都要在給定目錄下運行一遍
#include <stdio.h> int main(int argc, char ** argv) { printf("Hello World"); }
3.用命令行編譯它
emcc h.c -s WASM=1 -o h.js


WebAssembly相關的接口 API

-
exports屬性: 一個對象,該對象包含從WebAssembly模塊實例導出的所有函數屬性
-
exports屬性:一個數組,內容是所有已聲明的接口的描述。
-
imports屬性和:一個數組,內容是所有已聲明的引用的描述。
-
參數:包含你想編譯的wasm模塊二進制代碼的ArrayBuffer的類型實例
{
module: 一個被編譯好的 WebAssembly.Module 對象.
instance: 一個WebAssembly.Instance對象
}
Example
fetch('simple.wasm').then(response => response.arrayBuffer() ).then(bytes => WebAssembly.instantiate(bytes) ).then(result => result.instance.exports // exports是wasm中輸出的 );
webassembly的未來展望
-
多線程
-
SIMD(單指令流多數據流)
-
64位尋址
-
流式編譯(在下載的同時編譯 WebAssembly 文件)
-
分層編譯器
-
隱式 HTTP 緩存

webassembly的使用場景及其限制
-
其實在大多數場景下我們都不需要用到webassembly。因為V8等JS引擎的優化帶來了巨大的性能提升,已經足夠讓JS應對絕大多數的普通場景了,所以只有在以上的少數場景下,我們才需要做這種“二次提升”
-
和很多其他特性一樣,兼容性同樣是webassembly的一道坎,現代瀏覽器雖然支持度良好,但是在國內IE泛濫的特殊情況下, 這仍然是對webassembly的一個挑戰。不過在桌面應用上或者一些對兼容性要求較低的工具型網頁運用上,webassembly已經生根發芽,甚至能夠遍地開花。
webassembly的產品案例


