Qu'est-ce que WebAssembly? La plate-forme Web de nouvelle génération expliquée

Depuis deux décennies maintenant, nous n'avons qu'un seul langage de programmation disponible pour une utilisation native dans un navigateur Web: JavaScript. La mort lente des plug-ins binaires tiers a exclu d'autres langages, tels que Java et le code ActionScript de Flash, en tant que citoyens de premier ordre pour le développement Web. D'autres langages Web, comme CoffeeScript, sont simplement compilés en JavaScript.

Mais maintenant, nous avons une nouvelle possibilité: WebAssembly, ou WASM pour faire court. WebAssembly est un petit format binaire rapide qui promet des performances quasi-natives pour les applications Web. De plus, WebAssembly est conçu pour être une cible de compilation pour n'importe quel langage, JavaScript n'étant que l'un d'entre eux. Avec tous les principaux navigateurs prenant désormais en charge WebAssembly, il est temps de commencer à réfléchir sérieusement à l'écriture d'applications côté client pour le Web pouvant être compilées en tant que WebAssembly.

Il convient de noter que les applications WebAssembly ne sont pas destinées à remplacer les applications JavaScript, du moins pas encore. Au lieu de cela, considérez WebAssembly comme un compagnon de JavaScript. Là où JavaScript est flexible, typé dynamiquement et livré via un code source lisible par l'homme, WebAssembly est rapide, fortement typé et livré via un format binaire compact.

Les développeurs doivent envisager WebAssembly pour les cas d'utilisation gourmands en performances tels que les jeux, le streaming musical, le montage vidéo et les applications de CAO.

Fonctionnement de WebAssembly

WebAssembly, développé par le W3C, est selon les mots de ses créateurs une «cible de compilation». Les développeurs n'écrivent pas directement WebAssembly; ils écrivent dans la langue de leur choix, qui est ensuite compilée dans le bytecode WebAssembly. Le bytecode est ensuite exécuté sur le client - généralement dans un navigateur Web - où il est traduit en code machine natif et exécuté à grande vitesse.

Le code WebAssembly est censé être plus rapide à charger, analyser et exécuter que JavaScript. Lorsque WebAssembly est utilisé par un navigateur Web, il y a toujours la surcharge de téléchargement du module WASM et de sa configuration, mais toutes choses étant égales par ailleurs, WebAssembly s'exécute plus rapidement. WebAssembly fournit également un modèle d'exécution en bac à sable, basé sur les mêmes modèles de sécurité qui existent actuellement pour JavaScript.

À l'heure actuelle, l'exécution de WebAssembly dans les navigateurs Web est le cas d'utilisation le plus courant, mais WebAssembly est censé être plus qu'une solution Web. Finalement, à mesure que la spécification WebAssembly évolue et que de plus en plus de fonctionnalités y arrivent, elle peut devenir utile dans les applications mobiles, les applications de bureau, les serveurs et autres environnements d'exécution.

Cas d'utilisation de WebAssembly

Le cas d'utilisation le plus basique de WebAssembly est une cible pour écrire un logiciel intégré au navigateur. Les composants compilés dans WebAssembly peuvent être écrits dans l'un des nombreux langages; la charge utile WebAssembly finale est ensuite livrée via JavaScript au client.

WebAssembly a été conçu en gardant à l'esprit un certain nombre de cas d'utilisation basés sur un navigateur à haute performance: jeux, diffusion de musique, édition vidéo, CAO, cryptage et reconnaissance d'image, pour n'en citer que quelques-uns.

Plus généralement, il est instructif de se concentrer sur ces trois domaines lors de la détermination de votre cas d'utilisation WebAssembly particulier:

  • Code hautes performances qui existe déjà dans un langage ciblable. Par exemple, si vous avez déjà une fonction mathématique à grande vitesse écrite en C et que vous souhaitez l'intégrer dans une application Web, vous pouvez la déployer en tant que module WebAssembly. Les parties de l'application les moins critiques pour les performances et les utilisateurs peuvent rester en JavaScript.
  • Code hautes performances qui doit être écrit à partir de zéro, où JavaScript n'est pas idéal. Auparavant, on aurait pu utiliser asm.js pour écrire un tel code. Vous pouvez toujours le faire, mais WebAssembly se positionne comme une meilleure solution à long terme.
  • Portage d'une application de bureau vers un environnement Web. De nombreuses démos technologiques pour asm.js et WebAssembly entrent dans cette catégorie. WebAssembly peut fournir un substrat pour des applications qui sont plus ambitieuses qu'une simple interface graphique présentée via HTML. (Voir les démos WebDSP, Zen Garden et Tanks.) Ce n'est cependant pas un exercice trivial, car toutes les façons dont l'application de bureau s'interface avec l'utilisateur doivent être mappées à des équivalents WebAssembly / HTML / JavaScript.

Si vous avez une application JavaScript existante qui ne pousse aucune enveloppe de performances, il vaut mieux la laisser seule à ce stade du développement de WebAssembly. Mais si vous avez besoin de cette application pour aller plus vite, WebAssembly peut vous aider.

Prise en charge du langage WebAssembly 

WebAssembly n'est pas destiné à être écrit directement. Comme son nom l'indique, cela ressemble plus à un langage d'assemblage, quelque chose à consommer par la machine, qu'à un langage de programmation de haut niveau et convivial. WebAssembly est plus proche de la représentation intermédiaire (IR) générée par l'infrastructure du compilateur de langage LLVM que comme C ou Java.

Ainsi, la plupart des scénarios d'utilisation de WebAssembly impliquent d'écrire du code dans un langage de haut niveau et de le transformer en WebAssembly. Cela peut être fait de trois manières simples:

  • Compilation directe. La source est traduite en WebAssembly via la propre chaîne d'outils du compilateur du langage. Rust, C / C ++, Kotlin / Native et D ont désormais tous des moyens natifs d'émettre WASM à partir de compilateurs prenant en charge ces langages.
  • Outils tiers. Le langage n'a pas de support natif de WASM dans sa chaîne d'outils, mais un utilitaire tiers peut être utilisé pour convertir en WASM. Java, Lua et la famille de langages .Net ont tous un support comme celui-ci.
  • Interpréteur basé sur WebAssembly. Ici, le langage lui-même n'est pas traduit en WebAssembly; plutôt, un interpréteur pour le langage, écrit en WebAssembly, exécute le code écrit dans le langage. C'est l'approche la plus lourde, car l'interpréteur peut contenir plusieurs mégaoctets de code, mais elle permet au code existant écrit dans le langage de s'exécuter presque sans changement. Python et Ruby ont tous deux des interpréteurs traduits en WASM.

Fonctionnalités de WebAssembly

WebAssembly en est encore à ses débuts. La chaîne d'outils et la mise en œuvre de WebAssembly restent plus proches de la preuve de concept que de la technologie de production. Cela dit, les dépositaires de WebAssembly visent à rendre WebAssembly plus utile grâce à une série d'initiatives:

Primitives de récupération de place

WebAssembly ne prend pas directement en charge les langues qui utilisent des modèles de mémoire récupérés. Les langages comme Lua ou Python ne peuvent être pris en charge qu'en limitant les ensembles de fonctionnalités ou en intégrant l'intégralité du runtime en tant qu'exécutable WebAssembly. Mais des travaux sont en cours pour prendre en charge les modèles de mémoire récupérés indépendamment du langage ou de l'implémentation.

Filetage

La prise en charge native du threading est commune aux langages tels que Rust et C ++. L'absence de prise en charge des threads dans WebAssembly signifie que des classes entières de logiciels ciblés WebAssembly ne peuvent pas être écrites dans ces langages. La proposition d'ajouter un thread à WebAssembly utilise le modèle de thread C ++ comme l'une de ses inspirations.

Opérations de mémoire en masse et SIMD

Les opérations de mémoire en masse et le parallélisme SIMD (instruction unique, données multiples) sont indispensables pour les applications qui broient des piles de données et ont besoin d'une accélération native du processeur pour ne pas s'étouffer, comme l'apprentissage automatique ou les applications scientifiques. Des propositions sont sur la table pour ajouter ces fonctionnalités à WebAssembly via de nouveaux opérateurs.

Constructions de langage de haut niveau

De nombreuses autres fonctionnalités envisagées pour WebAssembly mappent directement vers des constructions de haut niveau dans d'autres langages.

  • Les exceptions peuvent être émulées dans WebAssembly, mais ne peuvent pas être implémentées de manière native via le jeu d'instructions de WebAssembly. Le plan proposé pour les exceptions implique des primitives d'exception compatibles avec le modèle d'exception C ++, qui pourraient à leur tour être utilisées par d'autres langages compilés en WebAssembly.
  • Les types de référence  facilitent le transfert d'objets utilisés comme références à l'environnement hôte. Cela rendrait le garbage collection et un certain nombre d'autres fonctions de haut niveau plus faciles à implémenter dans WebAssembly.
  • Appels de queue , un modèle de conception utilisé dans de nombreuses langues.
  • Fonctions qui renvoient plusieurs valeurs , par exemple via des tuples en Python ou C #.
  • Opérateurs d'extension de signe , une opération mathématique de bas niveau utile. (LLVM les prend également en charge.)

Outils de débogage et de profilage

L'un des plus gros problèmes avec JavaScript transpilé était la difficulté du débogage et du profilage, en raison de l'incapacité de corréler entre le code transpilé et la source. Avec WebAssembly, nous avons un problème similaire, et il est traité de la même manière (prise en charge de la carte source). Voir la note du projet sur le support d'outillage prévu.