WebAssembly : Comment le langage assembleur du Web a conquis les développeurs

S’il est possible d’écrire du WebAssembly natif, un langage de bas niveau, c’est bien la capacité de compiler de multiples langages en Wasm qui constitue la grande force de la solution.
Va-t-il réussir là où le Java a échoué ? WebAssembly ne semblait être qu’une solution pour faire tourner du C/C++ dans le navigateur web, une technologie qui séduit et qui pourrait bien avoir un impact majeur dans le développement d’application. En décembre 2019, le W3C faisait de WebAssembly un standard du Web, au même titre que les HTML et JavaScript. Ce que certains appellent par un raccourci un peu rapide le langage «assembleur du Web» doit donc être implémenté dans tout navigateur web digne de ce nom. Une solution technique qui ouvre la voie au déploiement facile d’applications C/ C++ ou Rust dans le navigateur web avec une performance proche du code natif, mais pas seulement. Non seulement les compilateurs de nombreux langages sont en train d’être adaptés pour générer du bytecode WebAssembly, mais celui-ci brise déjà les frontières du navigateur.

WebAssembly a séduit les développeurs les plus puristes

Beaucoup de jeunes développeurs l’ont aujourd’hui perdu de vue, mais il fut une époque où le seul moyen pour développer une application performante était de coder en C et en assembleur. L’assembleur, c’était l’assurance de pouvoir tirer la quintessence du processeur, de créer l’application la plus rapide qui soit. Par la suite, l’arrivée de compilateurs ultra-optimisés a quelque peu brouillé les cartes et l’assembleur est devenu un sport d’élite. Néanmoins, WebAssembly ravive cette flamme du code ultra compact chez les codeurs même s’il ne s’agit pas, stricto sensu d’un retour de l’assembleur estime Antoine Viau, architecte logiciel et développeur freelance : « J’ai trouvé l’approche intéressante. Écrire en WebAssembly natif comme à une certaine époque est possible – via le format WAT, WebAssembly Text Format), mais ça n’a que peu d’intérêt car les compilateurs produisent aujourd’hui un code plus performant qu’un humain ne peut le faire. Dire que c’est du langage assembleur pour le Web n’a pas tellement de sens, c’est un abus de langage. C’est avant tout un format d’instructions binaire. » L’idée de WebAssembly est de compiler un code proche du natif qui va s’exécuter de manière très rapide dans le navigateur. WebAssembly ne se pose pas en rival de JavaScript, mais comme un langage compagnon pour les parties de l’application qui nécessitent une grosse performance. « Si on veut développer une application de montage vidéo dans le navigateur, par exemple, les filtres que l’on va appliquer aux flux vidéo seront développés en WebAssembly à partir d’un langage adapté (C, Rust), mais tout ce qui est interface, gestion de la souris, l’interface utilisateur dans son ensemble sera développée en HTML, CSS et JavaScript. » WebAssembly permet de réutiliser dans le navigateur bon nombre de vieilles librairies C qu’il aurait été coûteux de réécrire. C’est aussi un moyen relativement simple pour beaucoup de fans de rétro-gaming de créer des émulateurs web pour leurs machines préférées. Le schéma original d’une application Wasm nécessite le JavaScript pour s’exécuter dans le navigateur et avoir notamment accès au DOM.

Une communauté très active enrichit l’écosystème WASM

Outre la promesse d’une performance notoirement supérieure à cette du JavaScript, WebAssembly peut potentiellement supporter n’importe quel langage. Actuellement les deux principaux langages pour développer pour WebAssembly sont C/C++ et Rust, mais cette liste de langage grossit rapidement avec Go, Java, Lua, Haskell, etc. Et si WebAssembly est nativement dépourvu de fonction de Garbage Collector, un runtime permet de remédier à cela et faire tourner des langages tels que Java ou Go. L’approche permet aussi de constituer des applications dont les modules et librairies ont été développées dans des langages différents sans difficulté. Ce support de multiples langages a particulièrement intéressé Quentin Adam, le fondateur de Clever-Cloud. Le fournisseur de services cloud exploite WebAssembly depuis quelque temps, notamment sur l’écran d’administration des services de Clever-Cloud mais le CSP va s’appuyer sur WebAssembly pour déployer son offre Functions as a Service. «Nous n’étions pas emballés à l’idée de monter une offre où des processus allaient s’exécuter en parallèle sur une même machine. Aller vers des machines virtuelles lancées à chaque appel de fonction était une approche bien trop lourde, car une VM demande quelques secondes pour démarrer. Nous n’avons pas besoin d’Unix complet et de Posix pour faire tourner une simple fonction, donc nous avons créé de mini-VM, des unikernel qui se lancent en quelques microsecondes et la brique qui exécute les fonctions, c’est WebAssembly, ce qui permet d’afficher une compatibilité C, C++, Kotlin, etc. Le résultat est incroyable puisque nous avons fait tourner un réseau neuronal dans une fonction qui s’exécute sur un unikernel en quelques microsecondes.» Ce service de Functions as a Service est déjà exploité par certaines applications internes de Clever-Cloud et sera commercialement lancé en bêta au premier trimestre 2020. Autre atout non négligeable de WebAssembly pour un fournisseur de services cloud, il a été conçu pour fonctionner dans le sandbox du navigateur. Un fournisseur de services cloud a l’assurance qu’une tâche Wasm ne va pas pouvoir fureter dans les données d’autres instances. Cette sécurité peut paraître paradoxale alors qu’une récente étude montrait que la moitié des sites web utilisant WebAssembly exposent des malwares… il s’agit en fait de logiciels de crypto-mining inoffensifs pour les fichiers mais s’exécutant à l’insu de l’internaute, preuve s’il en faut de la puissance de la solution… et de la facilité de porter du code existant dessus. Liste des langages pouvant être compilés en WebAssembly.

WebAssembly, un CPU virtuel, mais pas seulement

Une autre caractéristique qui peut être considérée comme un manque de WebAssembly, la solution est conçue à l’origine comme un CPU virtuel amené à exécuter le code qu’on lui envoie. Celui-ci ne dispose pas d’interfaces pour accéder aux ressources de la machine, ou encore au DOM, le modèle objet du navigateur. C’est normalement au JavaScript de se charger de l’accès aux fichiers et de l’aspect IHM. Après avoir traduit l’Unreal Engine version 3 en JavaScript en 2013, Epic et Mozilla ont porté en 2017 Unreal Engine 4 sur WebGL 2 et WebAssembly, une démonstration fonctionnant sur Firefox 52. La Bytecode Alliance, entité open source constituée par Mozilla, le fournisseur de services Cloud Fastly, Intel et Red Hat qui a formalisé le standard WebAssembly, développe le projet WASI (WebAssembly System Interface) qui vise à définir une interface standardisée pour permettre à WebAssembly de communiquer avec l’extérieur, notamment pour avoir accès au système pour faire des accès aux fichiers, aux threads, au réseau et à l’interface utilisateur à l’image de ce que fut Posix pour les systèmes Unix. Des applications professionnelles graphiques et représentant un historique de plusieurs millions de lignes de code compilées en WebAssembly, C'est possible! Autodesk en a fait la démonstration avec la version web de son hit AutoCAD. Le système de build mis en place par Autodesk permet à l’éditeur de générer toutes les versions d’AutoCAD à partir du même code source C++, y compris la version web, via Emscripten et WebAssembly. Parmi les premiers outils à générer du WebAssembly, Emscripten émule Posix. La solution permet d’embarquer des librairies nécessaires aux applications qui ont besoin d’une interface utilisateur. On peut générer du HTML, mais on peut tout autant embarquer un environnement graphique évolué complet. Mozilla et l’éditeur Epic ont ainsi fait tourner le moteur 3D Unreal 4 sans grandes difficultés… D’autres se sont amusés à faire tourner un Windows complet sous WebAssembly ainsi qu’un bon nombre d’émulateurs de consoles de jeux. Illustration extrême, la version WebAssembly d’AutoCAD développée par Kevin Cheung, Product Owner et Scrum Master chez Autodesk. Le développement initial de l’application remonte à plus de 30 ans maintenant et celle-ci compte 15 millions de lignes de code C++ en 83 modules. Pour la première version web d’AutoCAD, l’éditeur avait tenté de redévelopper son logiciel from scratch en Flash en 2009 puis il a privilégié la solution qui consiste à traduire le code C++ original en Java puis en JavaScript avec l’outil Tangible, puis le Google Web Toolkit en 2013. En 2015, Autodesk a choisi d’aller vers le cross-compiling du code C++ original d’AutoCAD avec Emscripten en 2015 et générer du langage Asm.js, pour finalement adopter Wasm en 2017 avec les outils Emscripten et Binaryen. Faire tourner AutoCAD ou un jeu 3D dans le navigateur pourrait sembler anecdotique mais WebAssembly cherche déjà à quitter le monde du Web. En effet, la Bytecode Alliance travaille désormais sur l’exécution de Wasm hors navigateur. L’idée est d’exécuter le code sans disposer du navigateur, ni même de VM JavaScript si l’application n’en a pas besoin. Dès lors, il devient possible de faire tourner du Wasm sur des serveurs, sur des objets connectés ou sous forme d’applications mobiles ou desktop. On pourrait bien alors disposer d’une plate-forme d’exécution commune pour toutes les applications, une plate-forme qui pourrait bien bousculer à l’avenir la façon de compiler et exécuter les applications.

Antoine Viau

Architecte logiciel – développeur freelance

« WebAssembly est, d’une certaine manière, le retour de la promesse initiale du Java d’écrire une fois et faire tourner n’importe où – Write once, Run anywhere. Avec WebAssembly, c’est la même idée et avec n’importe quel langage. On peut notamment repartir de l’existant et repartir d’une librairie écrite en C comme la librairie JPG, la compiler en WebAssembly et l’utiliser. Je l’ai fait dans le cadre d’une démo au Breizh camp. Cela fonctionne parfaitement et c’est d’une facilité déconcertante. »

Quentin Adam

Clever-Cloud fondateur

« Le gros intérêt de WebAssembly est de pouvoir récupérer du code patrimonial, du code C ou C++, de vieilles librairies et les réintégrer dans le front. Par exemple, nous avons eu besoin d’une librairie initialement écrite en Go. Nous avons recompilé le code Go en WasmL, ce qui nous a permis de ne pas réécrire cette librairie et passer un temps déraisonnable sur le projet. WebAssembly bénéficie d’une communauté qui se structure bien avec notamment un groupe de travail sur le Garbage Collector pour les langages tels que Python, Ruby. Le projet GraalVM d’Oracle dispose maintenant d’un backend WebAssembly si bien que n’importe quelle application Java va pouvoir tourner en WebAssembly. »