Analyses Profondes

WebAssembly expliqué : ce qu'il résout et où il atteint ses limites

koboshiCo-founder
·8 min de lecture
WebAssembly expliqué : ce qu'il résout et où il atteint ses limites
Résumé

WebAssembly n'est pas un remplaçant de JavaScript. C'est un format d'instructions binaires compact qui permet aux navigateurs d'exécuter du code compilé depuis C, C++, Rust et d'autres langages à une vitesse proche du natif. Cet article explique les limites des applications web pures, ce que WebAssembly résout, ses vrais compromis, les cas d'usage courants et pourquoi la conversion HEIC côté client serait impossible sans lui.

Déposez une photo HEIC dans un convertisseur en ligne. Il s'agit d'un conteneur qui encapsule des données image encodées en HEVC — la même compression H.265 que celle utilisée pour la vidéo 4K. Votre navigateur n'a pas de décodeur HEVC intégré, et écrire un tel décodeur entièrement en JavaScript serait lent, fragile et démesuré. Le décodeur dont vous avez réellement besoin est libheif, une bibliothèque C++ maintenue par strukturag. WebAssembly, c'est ce qui permet à ce décodeur C++ de tourner directement dans l'onglet du navigateur.

Cet exemple résume bien le principe. WebAssembly n'est pas un nouveau langage de programmation, ni un remplaçant de JavaScript. C'est un format d'instructions binaires portable et un environnement d'exécution isolé qui tourne dans le navigateur, aux côtés de JavaScript.

Ce qu'est WebAssembly en réalité

WebAssembly (Wasm) est une norme du W3C. Il définit un format d'instructions binaires compact et une machine virtuelle à base de pile. On n'écrit généralement pas du Wasm à la main ; on le compile depuis C, C++, Rust, Go, Zig, C# ou une liste croissante d'autres langages. Le résultat est un module .wasm que le navigateur télécharge, valide et exécute dans un bac à sable isolé en mémoire.

Tous les navigateurs majeurs prennent en charge WebAssembly depuis 2017. Le format de module est conçu pour être :

  • Compact : binaire, donc analysé plus vite qu'un code source JavaScript équivalent.
  • Rapide : compilé à l'avance en code machine par le navigateur.
  • Sûr : chaque module reçoit une mémoire linéaire isolée avec des vérifications de limites.
  • Indépendant du langage : tout langage ciblant le jeu d'instructions Wasm peut tourner sur le web.

Les limites du web traditionnel

JavaScript est un bon langage pour les interfaces utilisateur, les requêtes réseau et le code de liaison. Il est dynamiquement typé, garbage-collected et compilé JIT. Ces propriétés le rendent flexible, mais elles le rendent aussi imprévisible pour les calculs lourds.

Une pause du garbage collector peut figer le thread UI en pleine animation. Le temps de chauffe du JIT signifie que le même code peut s'exécuter à des vitesses différentes selon les moments. Pour les opérations numériques ou bit à bit — décodage d'image, encodage vidéo, cryptographie, simulation physique, grandes opérations matricielles — JavaScript est souvent un ordre de grandeur plus lent que la même logique compilée depuis C ou Rust.

L'autre limite est le verrouillage écosystémique. Des décennies de bibliothèques d'image, audio, vidéo et scientifiques sont écrites en C et C++. Les réécrire en JavaScript n'est pas une approche réaliste pour apporter ces capacités au web.

Pourquoi WebAssembly existe

Wasm a été créé pour résoudre deux problèmes à la fois :

  1. Exécuter du code natif existant dans le navigateur sans le réécrire en JavaScript.
  2. Donner aux applications web une couche d'exécution performante et prévisible pour les tâches auxquelles JavaScript n'a jamais été destiné.

Il est explicitement un compagnon de JavaScript, pas un successeur. Le DOM, la pile réseau et la plupart des API restent gérés par JavaScript. Wasm gère les calculs isolés ; JavaScript gère l'orchestration.

Ce que WebAssembly résout

  • Charges de travail liées au CPU : décodage d'images, transcodage vidéo, simulation physique, chiffrement de données.
  • Performance prévisible : pas de garbage collector, pas de courbe de chauffe JIT.
  • Réutilisation de code : apporter des bibliothèques éprouvées comme libheif, FFmpeg, SQLite et OpenCV dans le navigateur.
  • Confidentialité : les données sensibles peuvent être traitées localement au lieu d'être envoyées sur un serveur.
  • Exécution hors ligne : une fois le module .wasm téléchargé, il s'exécute sans aller-retour réseau.

Avantages et inconvénients

AspectAvantageLimite
PerformanceVitesse proche du natif pour les tâches numériques et liées à la mémoirePas plus rapide que le natif ; toujours contraint par le navigateur et l'appareil
PortabilitéUn même module tourne sur n'importe quel navigateur et OSNécessite un hôte JavaScript pour le DOM et la plupart des API navigateur
SécuritéMémoire linéaire isolée avec vérifications de limitesVulnérable aux canaux auxiliaires de type Spectre, comme tout code navigateur
ÉcosystèmeRéutilise des bases de code C/C++/Rust existantesL'interopérabilité avec JavaScript ajoute de la complexité et des surcoûts
DémarrageLe binaire s'analyse rapidementLe téléchargement et l'instanciation du module peuvent être lourds au premier chargement

Le constat honnête : Wasm rend le navigateur capable de travaux qui lui étaient auparavant impossibles, mais il ne fait pas disparaître les contraintes liées à l'exécution sur l'appareil de l'utilisateur.

Cas d'usage courants

WebAssembly est devenu la réponse par défaut quand une application web doit faire le gros du travail localement :

  • Retouche d'image et de vidéo : Figma, Photopea et outils similaires utilisent Wasm pour le rendu et les effets.
  • Transcodage vidéo : FFmpeg.wasm fait tourner FFmpeg dans le navigateur pour la conversion de formats.
  • Reconnaissance optique de caractères : Tesseract.js porte le moteur OCR Tesseract vers Wasm.
  • Jeux vidéo : Unity, Godot et Unreal Engine peuvent exporter vers Wasm pour des jeux basés sur le navigateur.
  • Analyse de données : Pyodide apporte Python et des paquets scientifiques ; sql.js fait tourner SQLite dans le navigateur.
  • Inférence d'apprentissage automatique : ONNX Runtime Web utilise un backend Wasm pour l'inférence CPU.
  • CAO et visualiseurs 3D : des noyaux géométriques complexes auparavant réservés au bureau.
  • Cryptographie : hachage, chiffrement et preuves à divulgation nulle de connaissance exécutées côté client.

Bibliothèques courantes basées sur WebAssembly

BibliothèqueOrigineFonction
heic-tolibheif via EmscriptenDécoder des images HEIC/HEIF et les convertir en JPEG, PNG ou bitmap dans le navigateur.
FFmpeg.wasmFFmpeg via EmscriptenTranscodage, remuxage et filtrage audio/vidéo entièrement côté client.
Tesseract.jsTesseract OCR via EmscriptenReconnaître du texte dans des images depuis le navigateur.
sql.jsSQLite via EmscriptenExécuter un moteur de base de données SQLite complet dans le navigateur avec un fichier en mémoire.
PyodideCPython via EmscriptenExécuter Python et des paquets comme NumPy, Pandas et SciPy sans backend.
ONNX Runtime WebONNX Runtime via EmscriptenExécuter des modèles d'apprentissage automatique ONNX sur CPU (Wasm) ou GPU (WebGL/WebGPU).

Toutes ces bibliothèques suivent le même schéma : compiler un projet natif éprouvé vers Wasm, puis l'exposer via une API JavaScript. C'est exactement là que réside l'intérêt pratique de WebAssembly.

Pourquoi la conversion en ligne HEIC vers JPG/PNG/WebP a besoin de WebAssembly

HEIC est un conteneur, pas un codec. Les données image réelles sont encodées en HEVC, qui est coûteux en calcul et soumis à des brevets. Aucun navigateur n'embarque de décodeur HEVC natif utilisable par les pages web. La conversion côté serveur est le recours évident, mais elle oblige à envoyer les photos de l'utilisateur sur un serveur.

L'alternative est d'expédier libheif — le même décodeur utilisé par les outils de bureau — compilé en WebAssembly. Quand vous utilisez notre convertisseur HEIC vers JPG, le décodage se fait dans votre navigateur :

  1. Le fichier est validé en lisant la signature de la boîte ftyp.
  2. Le module Wasm libheif décode le flux binaire HEVC localement.
  3. Le bitmap décodé est écrit sur un canvas et exporté en JPEG.

Le même module alimente HEIC vers PNG pour une sortie sans perte avec transparence, et HEIC vers WebP pour des tailles optimisées pour le web. Pas d'envoi vers un serveur, pas de traitement côté serveur, et aucun tiers ne voit l'image.

Ce flux de travail ne fonctionne que parce que WebAssembly peut exécuter un vrai décodeur d'images. JavaScript seul ne peut pas analyser du HEVC dans un délai raisonnable ; un envoi vers un serveur ruinerait la promesse de confidentialité. Wasm est le maillon qui manquait.

L'avenir de WebAssembly

Wasm dépasse peu à peu le navigateur. Le WebAssembly System Interface (WASI) définit une interface système portable qui permet aux modules Wasm de tourner sur des serveurs, des edge workers et des appareils IoT. Des runtimes comme Wasmtime, Wasmer et WasmEdge sont déjà déployés en production en dehors du navigateur.

La proposition de Component Model permettra aux modules Wasm d'exposer des interfaces typées et de se composer comme des bibliothèques, facilitant l'intégration d'un module Rust dans un hôte Python ou d'un service Go. WebAssembly GC ajoute un meilleur support pour les langages managés comme Java et Kotlin. Rien de tout cela ne vise à remplacer JavaScript dans le navigateur — il s'agit de faire de Wasm une cible d'exécution universelle et légère.

À l'intérieur du navigateur, la tendance va dans le même sens : davantage de capacités natives déplacées côté client, davantage d'outils qui préservent la confidentialité, et davantage de bibliothèques auparavant réservées au bureau qui tournent dans un onglet. WebAssembly n'est pas une fonctionnalité vedette que les utilisateurs remarquent, mais c'est de plus en plus ce qui permet aux tâches exigeantes de tourner sur le web.

Plus d'articles à lire