define

First look at the official website to give the definition.

WebAssembly (abbreviated Wasm) is a binary instruction format for a stack-based virtual machine. Wasm is designed as a portable compilation target for programming languages, enabling deployment on the web for client and server applications.

WebAssembly is a binary instruction set based on stack virtual machine. It can be used as the compiling target of programming language and can be deployed in Web client and server applications. In a word, Assembly runs on Web platform.

history

Recall why WebAssembly was created:

As we all know, JS is a dynamically typed language, where programs are written without regard to variable types and types can be changed at run time. Convenient for us developers, but problematic for the engine that runs it.



Due to the dynamic typing of JS, the interpreter will incur a certain performance cost in type judgment when executing code and slow down the execution speed. So the V8 engine uses JIT (just-in-time compilation) technology, which monitors some frequently executed code and compiles it into machine code that is executed directly by the CPU to speed up execution. But in some cases you have to reverse optimize and go back to the bytecode for execution.

With the continuous development of the front-end, the size and complexity of the project continue to increase, for some scenarios, the performance may not be able to meet, browser manufacturers have been exploring performance optimization methods.

WebAssembly became a World Wide Web Consortium (W3C) recommendation on December 5, 2019, making it the fourth language of the Web, along with HTML, CSS, and JavaScript.

compatibility

Method of use

There are three main steps from the.wasm source file to the instantiated object: load-> compile-> instantiation -> call.

  • Load: Read the WASM bytecode, usually fetched from the network by FETCH.
  • Compile: Compiles platform-specific code in the Worker thread.
  • Instantiation: Import some objects and methods from the host environment into a WASM module.
  • Call: A method in a WASM module is called from the object that has been instantiated in the previous step.

API

WebAssembly.instantiate(source, importObject)

WebAssembly.instantiateStreaming(resp, importObject)

  • Source: An ArrayBuffer or TypeDarray object containing the valid WASM module binary bytecode.
  • Resp: The response object after the fetch is called, resp.arrayBuffer () -> source.
  • ImportObject: Objects to be imported into a WASM module.

The API method encapsulates the two steps of compilation and instantiation. After the call, the loaded bytecode is converted into instance that has been instantiated, and the module method can be called through the instance object.

practice

First write a C++ program Fibonacci. Cc, Fibonacci number recursive writing.

#include <emscripten.h> extern "C" { EMSCRIPTEN_KEEPALIVE int fibonacci(int n) { if(n < 2) { return 1; } return fibonacci(n - 1) + fibonacci(n - 2); }}

Then install Emscripten to compile the C++ program into WASM format. (installation method can also be Google, feel trouble can go to https://github.com/thjjames/wasm to download)

$ git clone https://github.com/juj/emsdk.git
$ cd emsdk
$ ./emsdk install latest
$ ./emsdk activate latest
$ source ./emsdk_env.sh

Execute the following commands after installation,

emcc fibonacci.cc -s WASM=1 -O3 --no-entry -o fibonacci.wasm

-s WASM=1 indicates the program compiled into WebAssembly; -O3 indicates the degree of optimization of compilation; — The no-entry parameter tells the compiler that main has not been declared; -o Specifies the generated filename.

Put the fibonaccci. HTML and fibonaccci. wasm files in the root directory of any project and open IP :port/ fibonaccci. HTML to see (fetch only reads HTTPS? Address, if you open file directly, it will be reported across the field.

<! DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, Initial-scale =1.0" /> <title> </head> <script> function fibonacciJS(n) {if (n < 2) {return 1; } return fibonacciJS(n - 1) + fibonacciJS(n - 2); } const response = fetch('fibonacci.wasm'); const numArr = [10, 20, 30]; WebAssembly.instantiateStreaming(response).then( ({ instance }) => { const { fibonacci } = instance.exports; numArr.forEach(num => { let consoleTable = {}; let ccTime = 0; let jsTime = 0; for (let time = 0; time < 10; time++) { let start = performance.now(); fibonacci(num); ccTime += (performance.now() - start); start = performance.now(); fibonacciJS(num); jsTime += (performance.now() - start); } consoleTable[' WASM module call Fibonacci number ${num} time (average) '] = '${ccTime / 10}ms' consoleTable[' js module call Fibonacci number ${num} time (average)'] = `${jsTime / 10}ms` console.table(consoleTable); }) } ) </script> <body> </body> </html>

Chrome prints the result as shown below

You can see that WASM has significantly improved the running speed, and the time has been stable within half of JS!

application

WebAssembly in practice on eBay: 50 times faster WebAssembly based H.265 player

conclusion

For the front-end domain, WebAssembly can improve the performance of front-end projects in some scenarios, and some of the best libraries from the C/C++ domain can be compiled and run directly into the browser.