Web Assembly avec JavaScript et AssemblyScript
Il est possible aujourd'hui de faire du code qui sera compilé en WebAssembly de plusieurs manières.
Les deux manières les plus évidentes sont :
- Coder dans un langage bas niveau existant (Go, Rust, C++, etc.) pour ensuite générer un binaire (
wasm
) à l'aide d'outils spécifiques à chaque langage. - Utiliser le langage « texte » du WebAssembly (
wat
) pour le compiler directement en binaire (wasm
).
Nous allons aborder une approche intermédiaire, car nous allons utiliser AssemblyScript, un langage basé sur TypeScript conçu pour être compilé en WebAssembly.
Présentation
L'AssemblyScript est un langage de programmation open source et communautaire qui offre une optimisation pour WebAssembly. Il est de typage fort et présente de nombreuses similitudes avec le TypeScript, ce qui en fait un outil très intuitif sans avoir besoin de maîtriser un nouveau langage de programmation.
AssemblyScript respecte les spécifications du WebAssembly et se base sur binaryen, un compilateur rapide et performant en WebAssembly codé en C++.
Il ne faut pas oublier que JavaScript demeure indispensable dans un navigateur, car même le WebAssembly a besoin de lui pour interagir.
Compatibilité
L'AssemblyScript est compatible avec la plupart des navigateurs, mais aussi avec Node.js, Wasmtime et Wasmer.
Premier projet
Compilation
Il faut bien comprendre que lors de la compilation, l’AssemblyScript ne se compile pas directement en wasm
. Il faut plutôt le voir comme une transpilation en code wat
(similaire à la commande tsc
, qui transpile le TypeScript en JavaScript), qui est ensuite compilé en wasm
.
Options de compilations
Les options de compilation sont variées et peuvent se passer soit en argument de la commande de compilation (asc
), soit dans un fichier asconfig.json
à la racine du projet.
Les principales options de compilation sont les suivantes :
Optimisation :
--optimizeLevel
- Niveau d’optimisation du code (0-3), indique le niveau d’optimisation du code (au détriment de la taille du binaire), 3 étant le niveau d’optimisation le plus haut.
--shrinkLevel
- Indique à quel point le compilateur va tenter de réduire la taille du binaire (0-2).
- ⚠️ Il et déconseillé de mettre une valeur haute à ce paramètre si vous avez également mis des options d’optimisation du code.
Sortie :
--outFile
- Chemin de sortie du fichier
wasm
- Chemin de sortie du fichier
--textFile
- Chemin de sortie du fichier
wat
- Chemin de sortie du fichier
Débogage :
--debug
- Ajoute des informations de debug dans la version compilée (peut entrainer une réduction des performances)
Fichier de configuration
Les options mentionnées ci-dessus peuvent être spécifiées directement dans le fichier asconfig.json
de la façon suivante :
Binding & typage
La commande asc
non seulement compile notre code, mais génère aussi du typage pour permettre d'utiliser le code AssemblyScript depuis du code JavaScript ou TypeScript avec de l'autocomplétion et une certaine sécurité. Cela facilite considérablement le transfert entre les deux mondes.
Limitations
Typage
Il n'y a pas de cast "intelligent", les types entiers et flottants sont donc tous convertis en number
pour le TypeScript ou le JavaScript. Même si la plupart des types du TypeScript sont supportés, certains ne le sont pas.
Effets de bords
Il n'est pas possible d'accéder au DOM ou au réseau.
Code synchrone
Les fonctions asynchrones, intervalles, timer, timeout et observables sont à oublier : l'AssemblyScript est un langage synchrone.
Langage statique
Ce n’est pas un langage dynamique comme le TypeScript, on veut, pour que le WebAssembly soit efficace, que tout, soit explicite (les type, les retours). any, undefined, unknown
On peut avoir du typage alternatif, dans la limite du raisonnable :
Performances
Nous ne faisons pas le choix d'utiliser le WebAssembly à la légère.
En général, nous recherchons des performances accrues ou une sécurisation de notre code pour notre application web.
Nous allons tenter de déterminer dans quels cas l'utilisation du WebAssembly pourrait s'avérer être judicieuse, ou pas.
Benchmark
Ensemble de Mandelbrot
L’ensemble de Mandelbrot est une fractale composée d’un ensemble de points du plan complexe qui a pour formule :
Cette formule permet de générer des images représentant le parcours des nombres complexes sur une région carrée de son plan. Ces images sont très élaborées et constituent un terrain de jeu parfait pour tester le calcul et le rendu de certains programmes.
Exemple d’un ensemble de Mandlebrot