Skip to content

Supercharge Your Web Apps - Harnessing Web Assembly for High Performance

Updated: at 08:05 PM

Supercharge Your Web Apps - Harnessing Web Assembly for High Performance | abdadeel

Table of contents

Open Table of contents

Introduction

WebAssembly (Wasm) is a binary instruction format designed to be executed efficiently in web browsers. It serves as a complement to JavaScript, allowing developers to write performance-critical code in languages like Rust, C++, and C and run it in the browser. By compiling code to Wasm, it becomes platform-independent and can run at near-native speeds. Rust, a systems programming language known for its safety and performance, has gained popularity in the WebAssembly ecosystem due to its strong guarantees and seamless integration with Wasm. WebAssembly opens up new possibilities for web development by enabling the execution of complex tasks, such as game engines, image processing, and scientific simulations, with impressive performance.

Here is a short video that you might want to watch before continue reading.

Advantages of WebAssembly

Improved performance for computationally demanding jobs is one of WASM’s most persuasive features. For instance, WebAssembly can be much faster than regular JavaScript when doing complicated statistical calculations on enormous datasets. This is so that code can be executed considerably more quickly than it can in JavaScript thanks to WebAssembly’s highly optimised design. The portability of WebAssembly is another benefit. Cross-platform applications are simple to develop since WebAssembly code can be generated from a wide variety of languages and executed on any platform that does. Finally, security is another consideration in the architecture of WebAssembly. Code cannot access sensitive data or run harmful code because of the sandboxed execution environment it offers.

Using WebAssembly in Rust

Rust is a systems programming language that provides memory safety and performance. It is also a great language for writing WebAssembly code. Let’s take a look at how to use WebAssembly in Rust.

Setting up the project

To get started, we need to install a tool called wasm-pack. We can use cargo to install the tool

cargo install wasm-pack

Once we have wasm-pack installed, we can create a new Rust project and add the required functions. We can annotate these functions with the wasm-bindgen attribute, which takes care of all the things required to call these functions from JavaScript behind the scenes.

Setting up the Rust environment

Implementing the Fibonacci function in Rust

#[wasm_bindgen]
pub fn fib(n: usize) -> usize {
    match n {
        0 => 0,
        1 => 1,
        _ => fib(n - 1) + fib(n - 2),
    }
}

Building the Rust code for WebAssembly

Using on the frontend

import init, {
  add,
  greet,
  fib,
  alert_wasm,
} from "./wasm-tools/pkg/wasm_tools.js";

const app = document.getElementById("app");
const btn = document.getElementById("btn");
const btnWasmAlert = document.getElementById("btn-wasm-alert");

btn.addEventListener("click", handleTriggerFib);
btnWasmAlert.addEventListener("click", () => {
  alert_wasm("Hello from Wasm");
});

function updateContent(content) {
  const div = document.createElement("div");
  div.innerHTML = content;
  app.appendChild(div);
}

function fibJS(n) {
  if (n < 2) {
    return n;
  }
  return fibJS(n - 1) + fibJS(n - 2);
}

async function run() {
  await init();
  const res = add(1, 2);
  updateContent(`1 + 2 = ${res}`);
  const res2 = greet("Wasm Tools");
  updateContent(res2);
}

function measureExecutionTime(fn) {
  return function (...args) {
    const start = performance.now();
    const result = fn.apply(this, args);
    const end = performance.now();
    const executionTime = end - start;
    return { result, executionTime };
  };
}

function handleTriggerFib() {
  // JS
  const { result: res3, executionTime: time3 } =
    measureExecutionTime(fibJS)(40);
  updateContent(`fibJS(40) = ${res3} in ${time3}ms`);

  // Wasm
  const { result: res4, executionTime: time4 } = measureExecutionTime(fib)(40);
  updateContent(`fibWasm(40) = ${res4} in ${time4}ms`);

  // Web Worker
  const worker = new Worker("./worker.js");
  const start = performance.now();
  worker.addEventListener("message", event => {
    const { data } = event;
    const { res } = data;
    const end = performance.now();
    updateContent(`fibWorker(40) = ${res} in ${end - start}ms`);
    worker.terminate();
  });
  worker.postMessage({ n: 40 });
}

run();

Open html file in browser

application using webassembly for performance

Visit https://wasm-web-performance.vercel.app to see the application live.

Conclusion

In conclusion, WebAssembly is a powerful tool for optimizing web applications. It provides improved performance, portability, and security, making it an attractive option for web developers looking to optimize their applications. Rust is a great language for writing WebAssembly code, and wasm-pack makes it easy to compile and consume WebAssembly code in JavaScript.

Source Code

The source code for this project can be found here.

Live Demo

Rust WASM (wasm-web-performance.vercel.app)