WebAssembly
Qu'est-ce que WebAssembly ?
WebAssembly (Wasm) est un format d'instructions binaire conçu pour s'exécuter à une vitesse proche du natif dans le navigateur, aux côtés de JavaScript et non à sa place. Il offre une cible de compilation pour des langages comme C, C++, Rust ou Go, afin que du code exigeant en calcul s'exécute directement dans le navigateur sans plugin. Les modules Wasm tournent dans une machine virtuelle sandboxée que chaque navigateur majeur embarque nativement : le même binaire fonctionne sur Chrome, Firefox, Safari et Edge sans installation supplémentaire.
Ce format existe parce que JavaScript, bien que flexible, n'est pas toujours l'option la plus rapide pour les traitements lourds : montage vidéo, rendu 3D, simulations physiques, cryptographie ou traitement de grands volumes de données. WebAssembly comble cet écart. Il ne remplace pas JavaScript : il le complète, en prenant en charge les parties les plus gourmandes en calcul pendant que JavaScript continue de gérer le DOM, les événements et l'orchestration.
Fonctionnement de WebAssembly
Un flux Wasm classique part d'un code source dans un langage compilé, qu'une chaîne d'outils (Emscripten pour C/C++, wasm-pack pour Rust) transforme en module binaire .wasm. Le navigateur récupère ce module, le compile en code machine, puis l'expose à JavaScript via l'API WebAssembly.
Un exemple minimal : charger et appeler un module Wasm depuis JavaScript ressemble à ceci.
WebAssembly.instantiateStreaming(fetch('add.wasm'))
.then(({ instance }) => {
const result = instance.exports.add(2, 3);
console.log(result); // 5
});
Le module expose des fonctions (ici add) que JavaScript peut appeler directement, avec une exécution proche du natif puisque le code tourne comme des instructions machine compilées plutôt qu'interprétées.
Concepts et variantes clés
- Module : le binaire
.wasmcompilé, l'unité de code chargée puis instanciée. - Instance : une copie en cours d'exécution d'un module, avec sa propre mémoire et son propre état.
- Mémoire : un tampon linéaire et redimensionnable, partagé entre Wasm et JavaScript.
- Table : un tableau typé de références (souvent des fonctions), utilisé pour les appels indirects.
- WASI (WebAssembly System Interface) : une norme qui permet à Wasm de s'exécuter hors du navigateur, sur des serveurs ou en edge computing, avec un accès contrôlé au système de fichiers et au réseau.
Au-delà du navigateur, Wasm est de plus en plus utilisé côté serveur (fonctions edge, systèmes de plugins, environnements d'exécution sandboxés) car son modèle d'isolation sécurise le code sans recourir à un conteneur complet.
L'écosystème d'outils a mûri en conséquence : Emscripten compile des bases de code C/C++ existantes vers Wasm avec peu de modifications, wasm-bindgen et wasm-pack gèrent le pont avec Rust, et des runtimes comme Wasmtime ou Wasmer exécutent Wasm en dehors de tout navigateur. Des produits concrets s'appuient déjà sur cette pile en production, pas seulement à titre expérimental : Figma fait tourner son moteur de rendu en Wasm, AutoCAD a porté son moteur bureau sur le web grâce à lui, et Google Earth y recourt pour les parties de son moteur 3D qui exigent des performances proches du C++.
WebAssembly vs JavaScript
| Aspect | WebAssembly | JavaScript |
|---|---|---|
| Exécution | Compilé en code machine quasi natif | Interprété / compilé à la volée (JIT) |
| Usage type | Tâches lourdes en calcul (rendu, codecs, cryptographie) | Manipulation du DOM, logique applicative, orchestration |
| Langages sources | C, C++, Rust, Go, et plus | JavaScript, TypeScript |
| Accès au DOM | Aucun accès direct, passe par JavaScript | Direct et natif |
| Poids | Format binaire compact | Basé texte, plus volumineux à logique équivalente |
Bonnes pratiques et pièges courants
- Réserver WebAssembly aux traitements réellement gourmands en calcul, pas comme remplacement par défaut de JavaScript : le coût des allers-retours entre Wasm et JS peut annuler le gain de performance sur de petites tâches.
- Garder le binaire Wasm aussi léger que possible (tree-shaking, options de compilation), car il doit être téléchargé avant de pouvoir s'exécuter.
- Éviter les appels fréquents et unitaires entre JS et Wasm ; privilégier des transferts de données groupés via la mémoire partagée.
- Tester sur de vrais appareils, en particulier mobiles : le temps de compilation et d'instanciation compte dans le chargement initial, contrairement à un bundle JS déjà mis en cache par le navigateur.
- Piège courant : attendre un accès direct au DOM depuis Wasm. Toute mise à jour d'interface repasse par JavaScript.
Compatibilité navigateurs et impact sur la performance
WebAssembly est nativement supporté par tous les navigateurs modernes (Chrome, Firefox, Safari, Edge) sans polyfill, ce qui le rend exploitable en production sur un site public. Bien utilisé, il améliore les Core Web Vitals sur les pages gourmandes en calcul : un éditeur d'image ou un codec vidéo propulsé par Wasm répond plus vite qu'un équivalent tout-JavaScript, ce qui réduit l'Interaction to Next Paint (INP) sur ces interactions précises. Mal utilisé (un gros bundle Wasm chargé sur chaque page sans besoin réel), l'effet est inverse et pénalise le Largest Contentful Paint (LCP) en alourdissant le chargement initial. La règle à retenir : charger les modules Wasm à la demande, uniquement sur les pages et interactions qui en ont réellement besoin.
La compatibilité est rarement le point bloquant aujourd'hui ; l'arbitrage réel se joue sur le coût d'ingénierie face au bénéfice. Porter ou réécrire une base de code vers Wasm a du sens quand une fonctionnalité est réellement limitée par le calcul et que JavaScript est le goulot d'étranglement, pas quand l'objectif est simplement de rendre une page déjà rapide encore plus rapide.
WebAssembly chez BeBranded
Notre équipe intervient sur des applications web où la performance brute compte autant que l'expérience utilisateur : configurateurs 3D, outils d'édition média, calculs complexes côté client. Quand une approche JavaScript classique atteint ses limites, nous évaluons WebAssembly comme option technique dans le cadre de notre accompagnement Web apps, en pesant le gain de performance face à la complexité ajoutée.