WebAssembly – Webanwendungen auf der Überholspur

Wasm-Module benutzen

Ein weiterer Vorteil von Binding-Bibliotheken wie stdweb und wasm-bindgen: Sie können JavaScript-Module produzieren, die sich um das Laden eines Wasm-Moduls kümmern. Entwickler müssen also nicht direkt mit der WebAssembly-API arbeiten, sondern binden das Wasm-Modul wie ein ganz normales JavaScript-Modul ein. Dass dahinter eigentlich ein Wasm-Modul steckt, wissen die Nutzer nicht (s. Abb. 1).

Ein guter Wasm-Compiler generiert ein Wrapper-Modul in JavaScript, das sich um sämtliche Datenkonversionen kümmert. Der Benutzer bekommt im Idealfall nicht mit, dass er WebAssembly verwendet. (Abb. 1)

wasm-bindgen kann unter anderem verschiedene Wrapper-Skripte erzeugen, je nachdem in welcher Umgebung man das Wasm-Modul einsetzt. Ein Beispiel für das Einbinden eines Wasm-Moduls in JavaScript-Code ist in Listing 2 zu sehen. Dem Code sieht man das dahinterstehende WebAssembly-Modul nicht an. Lediglich der import-Befehl deutet darauf hin. Das nächste Listing zeigt zunächst ein WebAssembly-Modul namens alert_wasm, geschrieben in Rust. wasm-bindgen kümmert sich um Details wie Datenkonversion.

#![feature(use_extern_macros)]

extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;

// Wir importieren die JavaScript-alert()-Funktion.
#[wasm_bindgen]
extern {
fn alert(s: &str);
}

// Diese Funktion wird exportiert und
// kann von JavaScript aus benutzt werden
#[wasm_bindgen]
pub fn greet(who: &str) {
alert(&format!("Hello {}!", who));
}

Der folgende Code importiert das Wasm-Modul von oben und ruft seine greet-Funktion auf. Das Beispiel benötigt webpack.

const js = import("./pkg/alert_wasm");

js.then(js => {
js.greet("from wasm");
});

Der import-Befehl ist noch relativ jung. In der Funktionsschreibweise wie in zweiten Codebeispiel unterstützen Browser den Befehl noch nicht. Das macht die Verwendung eines Bundlers wie webpack nötig. Weitere Umgebungen, die wasm-bindgen unterstützt, sind Node.js und no-module. Letztere ist für Webseiten gedacht, die keinen Bundler verwenden können oder wollen, sowie für die Verwendung von Wasm-Modulen in Web-Workern. Die Verwendung von Web-Workern empfiehlt sich für Wasm-Funktionen, deren Ausführungszeit mehrere hundert Millisekunden überschreitet und damit nicht mehr in den Bereich von Interaktivität fällt. WebAssembly-Code wird im gleichen Thread ausgeführt wie JavaScript-Code und blockiert damit bei längerer Laufzeit auch das User Interface – der Benutzer kann keine Buttons mehr klicken und die Webseite erscheint eingefroren.