Faire tourner Stockfish dans le navigateur : ce que WebAssembly change

Sur OpeningBook, chaque position est analysée par Stockfish directement dans le navigateur, sans appel serveur. WebAssembly rend ça possible, mais le buzzword cache des contraintes concrètes qui changent la façon de concevoir l'application autour.
Ce que WASM apporte réellement
Stockfish est écrit en C++, optimisé depuis des années pour la performance brute. Compiler ce code en WebAssembly permet de l'exécuter dans le navigateur à une vitesse proche du natif, sans réécrire le moteur dans un autre langage. C'est la différence entre porter vingt ans d'optimisations d'un moteur d'échecs, et réimplémenter un évaluateur de position depuis zéro en JavaScript, avec toutes les régressions de performance que ça impliquerait.
La contrainte qu'on découvre vite : le threading
Le vrai piège n'est pas la compilation elle-même, mais l'exécution
multi-thread. Stockfish exploite plusieurs cœurs pour paralléliser la
recherche, mais WebAssembly multi-thread dans un navigateur nécessite
SharedArrayBuffer, qui exige à son tour des en-têtes de sécurité HTTP
précis (Cross-Origin-Opener-Policy, Cross-Origin-Embedder-Policy). Sans
ces en-têtes correctement configurés côté serveur (ou côté Vercel dans mon
cas), le moteur retombe silencieusement en mode single-thread, avec une
perte de performance qui n'est pas évidente à diagnostiquer si on ne sait
pas où chercher.
Navigateur
┌────────────────────────────────────────────────────────┐
│ Page OpeningBook │
│ │ │
│ ▼ │
│ Web Worker ──▶ Stockfish.wasm ──▶ résultat d'analyse │
│ ▲ │
│ │ nécessite SharedArrayBuffer pour le multi-thread │
│ │ │
│ En-têtes HTTP requis sur la réponse du serveur : │
│ Cross-Origin-Opener-Policy: same-origin │
│ Cross-Origin-Embedder-Policy: require-corp │
└────────────────────────────────────────────────────────┘
Sans ces deux en-têtes, le navigateur refuse silencieusement d'allouer un
SharedArrayBuffer partagé entre threads, et Stockfish continue de
fonctionner, mais en mode single-thread, sans erreur visible dans la
console qui pointe vers la cause réelle.
Le compromis architecture qui en découle
Faire tourner l'analyse côté client plutôt que côté serveur change la répartition des responsabilités : plus besoin d'API d'analyse à maintenir, pas de coût serveur qui grandit avec le nombre d'utilisateurs simultanés, mais en échange, chaque appareil doit être capable de faire tourner un moteur d'échecs correctement optimisé. Sur un ordinateur récent, la différence est invisible. Sur un appareil plus ancien, l'expérience se dégrade, et il faut prévoir un mode de repli (profondeur d'analyse réduite, ou UI qui indique clairement que le calcul prend du temps).
Client vs serveur, le compromis résumé
| Aspect | Analyse côté client (WASM) | Analyse côté serveur |
|---|---|---|
| Coût d'infrastructure | Nul, indépendant du nombre d'utilisateurs | Croît avec le nombre de calculs simultanés |
| Latence perçue | Dépend de l'appareil de l'utilisateur | Constante, contrôlée par le serveur |
| Cohérence entre utilisateurs | Peut varier selon le matériel (profondeur, vitesse) | Identique pour tout le monde |
| Confidentialité des positions | Ne quitte jamais le navigateur | Transite par le serveur |
| Complexité de mise en place | En-têtes COOP/COEP, gestion du Web Worker | Une API HTTP classique |
La ligne confidentialité n'est pas un détail secondaire pour un outil familial : une position d'échecs analysée par un enfant n'a aucune raison de transiter par un serveur, et le choix WASM la garde entièrement locale par construction, pas par configuration additionnelle.
Pourquoi ce choix, malgré la complexité
Pour un outil familial comme OpeningBook, où chaque analyse de position est consultée ponctuellement plutôt qu'en continu, l'absence de coût serveur récurrent l'emporte largement sur la complexité de mise en place initiale. C'est un arbitrage qui ne se généralise pas : sur un produit avec des milliers d'utilisateurs simultanés et des exigences de cohérence d'analyse, un moteur centralisé côté serveur resterait probablement le meilleur choix. Le bon choix d'architecture dépend toujours du profil d'usage réel, pas d'une préférence technologique a priori pour le « tout côté client ».