WebAssembly with Web APIs

What Are Web APIs?

Web APIs are a collection of browser-provided functionalities that enable developers to:

  • Manipulate web page content (DOM).
  • Make network requests (Fetch API).
  • Render 2D and 3D graphics (Canvas, WebGL).
  • Handle user input (Mouse and Keyboard events).
  • Manage audio and video (Web Audio API).
  • Enable real-time communication (WebRTC).

While JavaScript traditionally accesses Web APIs, WebAssembly uses JavaScript as a bridge to communicate with these APIs, as Wasm itself does not natively call them.

Why Use WebAssembly with Web APIs?

Combining WebAssembly with Web APIs is essential when:

  • Performance is critical: Offload computationally heavy tasks to WebAssembly and let Web APIs handle user interaction.
  • Complex rendering is needed: Use WebGL with Wasm for games or simulations.
  • Real-time processing is required: For applications like live video manipulation or real-time data visualization.

How WebAssembly Interacts with Web APIs

WebAssembly doesn’t have direct access to Web APIs. The integration follows these steps:

  1. JavaScript acts as a bridge: WebAssembly sends or receives data via JavaScript.
  2. Wasm performs intensive tasks: For example, physics calculations or encryption.
  3. Web APIs manage UI or interactions: For example, drawing on a canvas or fetching data.

Examples of WebAssembly with Web APIs

Example 1: Updating the Canvas with WebAssembly

This example demonstrates how WebAssembly calculates data and interacts with the Canvas API to draw the result.

1. Write WebAssembly Code in C

#include <stdint.h>

// Declare a JavaScript function for drawing
extern void draw_on_canvas(int result);

void calculate_and_draw(int a, int b) {
int sum = a + b;
draw_on_canvas(sum); // Pass the result to JavaScript
}

2. Compile to WebAssembly

Use Emscripten to compile:

emcc calculate.c -s EXPORTED_FUNCTIONS="['_calculate_and_draw']" -s MODULARIZE -o calculate.js

3. JavaScript to Bridge Wasm and Canvas

// Import the WebAssembly module
const Module = require('./calculate.js');

Module().then((instance) => {
// Implement the JavaScript function called by WebAssembly
window.draw_on_canvas = function (result) {
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');

// Clear the canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);

// Draw the result
ctx.font = '20px Arial';
ctx.fillStyle = 'blue';
ctx.fillText(`Result: ${result}`, 50, 50);
};

// Call the Wasm function
instance._calculate_and_draw(5, 15);
});

4. HTML File

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WebAssembly Canvas Example</title>
</head>
<body>
<canvas id="canvas" width="400" height="200" style="border:1px solid #000;"></canvas>
<script src="calculate.js"></script>
<script src="main.js"></script>
</body>
</html>

Example 2: Fetching Data Using the Fetch API

1. WebAssembly Module in C

#include <stdint.h>

// Declare a JavaScript function to display data
extern void display_data(const char* data);

void fetch_data() {
const char* response = "Data fetched from API";
display_data(response); // Call JavaScript to show data
}

2. Compile the Module

emcc fetch.c -s EXPORTED_FUNCTIONS="['_fetch_data']" -s MODULARIZE -o fetch.js

3. JavaScript to Fetch and Display Data

const Module = require('./fetch.js');

Module().then((instance) => {
// JavaScript function to display data
window.display_data = function (data) {
document.body.innerHTML = `<p>${data}</p>`;
};

// Trigger the WebAssembly function
instance._fetch_data();
});

Benefits of WebAssembly with Web APIs

  1. High Performance: WebAssembly accelerates complex calculations, leaving Web APIs to handle interactions.
  2. Seamless Integration: Combining Wasm with Web APIs bridges low-level computations and high-level interactions.
  3. Cross-Language Compatibility: Write performance-critical logic in C, C++ or Rust and interact with browser-native JavaScript APIs.

Challenges in Integrating WebAssembly and Web APIs

  1. Limited Direct Access: WebAssembly needs JavaScript as an intermediary to call Web APIs.
  2. Data Passing Overhead: Transferring large datasets between Wasm and JavaScript can impact performance.
  3. Debugging Complexity: Debugging issues across Wasm and JavaScript requires specialized tools.

Leave a Comment