Logo EPK

WebAssembly : futur du web?

J'ai eu l'occasion de faire ce talk dans le cadre des HumanTalks Lyon, qui acceuillent des présentations "généralistes". L'objectif de cette présentation est de présenter les grandes idées derrière le WebAssembly, des perspectives en terme d'architecture et de performances sur le très long terme, avant de regarder ce qui bloque actuellement.

Les Slides

Un résumé

Dans les navigateurs web, un seul langage de programmation règne : JavaScript. Cependant, le javascript a de nombreux inconvénients : sa nature interprétée (qui nuit aux performances), son manque de typage (qui nuit à sa maintenabilité). En réponse à cela, un groupe de travail du W3C à mis en œuvre un langage qui garderait les avantages du JS (à savoir sa portabilité, facteur important du Web), et qui compenserait certaines de ses lacunes, notamment en termes de temps d’exécution.

C’est ainsi qu’est né le WebAssembly, un assembleur (donc un langage avec un instruction-set le plus petit possible) exécuté directement par le navigateur, et dont les objectifs sont de faciliter les traitements calcul-intensifs. A date de ce rapport, il est possible de compiler vers du WebAssembly depuis plus de 50 langages (dont les leaders du marché du « compilé » : le C, C++ et les nouveaux comme le Rust).

WebAssembly propose deux grands avantages face au JS :

  • Les optimisations sont calculées par le compilateur lors de la compilation (au lieu d’être déduites avec un overhead lors de l’exécution).

  • Le code résultant est plus léger, toujours grâce à la compilation qui transforme des représentations de code en texte vers du binaire (notamment)

En plus d’être utilisé côté navigateur, il existe le même besoin de performance côté serveur, avec des problématiques supplémentaires : les différents langages utilisés pour du backend pouvaient effectuer des appels aux librairies standard, afin notamment d’interagir avec des sockets (pour des bases de données) ou avec le système de fichiers (pour des logs ou autres). Afin de combler ce besoin, une surcouche au WebAssembly a été inventée : la WebAssembly System Interface (WASI). WASI fournit une interface unifiée, avec la charge au système d’exécution de fournir les bindings avec les appels systèmes sur le système hôte. Par exemple, pour les sockets, l’implémentation en Node se servira d’appels POSIX pour les sockets, là ou l’implémentation sur navigateur se rattachera à ce qui est possible avec fetch et les WebSockets.

Ainsi, avec WASI, WebAssembly devient un langage aussi expressif que le JS. Une question reste donc en suspens : pourquoi ne pas s’en servir partout ? Le seul inconvénient du WebAssembly est qu’il est impossible pour lui d’accéder aux API JS, telles que celles du DOM.

Sur le long terme, il devient intéressant de considérer des architectures comme celle présentée ci-dessous : le WebAssembly s’occupant du plus de calculs possibles et des tâches métiers, là ou le JS qui est moins performant se contente de gérer la vue et l’affichage des valeurs.

appels de fonctions

HTTP

View
(JS)

ViewModel
(WASM)

Model
(API)

Une architecture possible pour déléguer les calculs totalement à du WebAssembly

L’ultime question en suspens est de savoir comment bien intégrer du code WebAssembly à des projets existants ? Il y a une multiplication des toolchains : les suites logicielles permettant de produire des projets depuis le code source (il en faudrait une pour JS avec son bundler, et une pour le langage source du WebAssembly). Cette multiplication est au détriment des développeurs qui auront ainsi des temps d’installation des projets plus longs alors qu’ils n’ont pas forcément à utiliser la compilation d’une partie du projet. L’idée finale étant donc :

  • Isoler la toolchain qui produit le WebAssembly (et son code source) dans un repository séparé, qui produira à la fin un packet npm

  • Avoir son projet JS « classique », basé sur npm, qui importera la partie WebAssembly de manière « agnostique » comme un simple paquet npm