Web Assembly - Formation

Présentation de la formation

Encore assez jeune, le WebAssembly fait beaucoup parler de lui.
Il permettrait à notre navigateur de lancer des programmes codés autrement qu'en JavaScript.

Comment exploiter cette technologie afin de rendre plus "puissant" notre navigateur, dans un monde où les applications clientes "lourdes" sont délaissés au profit d'applications web ?

Certains même le compare à Docker et estiment même qu’il remet en cause son existence. Pourquoi est-ce le cas ? Y a-t-il réellement une plus-value à vouloir utiliser WebAssembly côté serveur ?

Ce cours a été écrit dans le cadre d'un projet de validation de notre diplôme de master.
Il a été coécrit par :

Fondamentaux

Fondamentaux

Qu'est-ce que le Web Assembly ?

Qu’est-ce qui a motivé la création du WebAssembly ?

Aujourd'hui, en moyenne, les humains passent 6 heures et 56 minutes sur Internet chaque jour, ce qui est considérable et leur navigation est une grande partie de ce temps.

Le Web 2.0 a apporté de nombreux changements aux usages d'Internet. On peut maintenant créer de véritables applications dans le navigateur. Les derniers moteurs JavaScript, conjointement à l'arrivée de nouveaux standards web tels que le WebGL, ont permis une transformation radicale de l'utilisation d'Internet. Nous sommes passés d'un monde de consommation à un monde interactif.

Ces nouvelles utilisations d'Internet ne sont pas en adéquation avec l'idée première de JavaScript. Bien que JavaScript ait été amélioré, son caractère en tant que langage de script, son fonctionnement par interprétation et la rétrocompatibilité qu'il doit conserver depuis 1997 font qu'il ne peut plus satisfaire tous les usages du web.

Cependant, comme nous le découvrirons plus en détail plus tard, JavaScript demeure obligatoire pour l'utilisation du web et le WebAssembly n'est adapté qu'à peu de cas d'utilisation du web.

Quelles sont les prédécesseurs et alternatives ?

Avant l'arrivée de WebAssembly et même avant l'amélioration des performances de JavaScript grâce à la compilation JIT (Juste-à-Temps), il y avait déjà des alternatives à JavaScript pour exécuter du code dans le web. Voici une liste des principales solutions qui étaient disponibles :

Ces solutions, qui ont été abandonnées pour plusieurs raisons, étaient notamment handicapées par la nécessité d'installer un logiciel sur le PC de l'utilisateur, ce qui comportait des risques de sécurité et de commodité.

L'avènement des appareils mobiles a encore affaibli cette technologie.

Une autre possibilité est d'utiliser JavaScript avec les nouveaux standards, ce qui n'offre pas les mêmes performances, mais reste une alternative intéressante par rapport au WebAssembly. Celui-ci présente l'avantage de s'appuyer sur le langage et l'écosystème JavaScript, bien rodés.

Qu’est-ce que c’est que le WebAssembly ?

Le WebAssembly (WASM) est une toute nouvelle méthode d'exécution d'instructions non seulement dans le navigateur, mais aussi dans d'autres contextes. Après de nombreuses tentatives externes, le World Wide Web Consortium (W3C) a proposé une solution.

Cette solution devait répondre aux objectifs suivants :

Le point "Part of the Web" a pour but d'éviter les problèmes rencontrés par le passé lors de l'installation de Java et de l'exécution de code en dehors du navigateur. De plus, il fait référence à la grande compatibilité du Web et à l'utilisation de certaines API Web telles que BigInt.


Le WebAssembly, également appelé WASM, est une ISA (Instruction Set Architecture) virtuelle.

Une ISA est un modèle abstrait des opérations de base qu'il est possible d'effectuer avec un ordinateur.

Généralement, une ISA est un format binaire conçu pour s'exécuter sur une machine spécifique ou une architecture de processeur particulière. Le WebAssembly ne fait pas partie de cette catégorie, car il est destiné à une machine virtuelle et non à une machine physique.

L'ISA du WebAssembly a été conçue pour être compacte, portable et sécurisée. Les ISA classiques ne sont pas nécessairement conçues pour être compactes, mais le WebAssembly est destiné à être servi par un serveur web.

En raison de son jeu d'instructions, le WebAssembly n'est pas destiné à être codé directement. Il existe un langage assembleur qui permet d'avoir une représentation de chacune des instructions du WebAssembly, appelé WAT. Il est principalement utilisé pour le débogage, l'apprentissage ou pour aller plus loin dans l'optimisation.

Bien qu'il ne soit pas destiné à être codé directement, il peut être utilisé comme cible de compilation pour d'autres langages. Ceci permet d'ouvrir le web à d'autres langages que le JavaScript.


Le jeu d'instruction de WebAssembly dans sa version 1.0 contient 172 instructions. C'est assez peu, compte tenu de la duplication en fonction des types. En réalité, il y a environ cinquante instructions différentes. Ce nombre va augmenter avec le temps et les ajouts au standard, mais apprendre le WebAssembly maintenant est une belle opportunité, car en prenant les ajouts petit à petit, vous aurez une meilleure compréhension.

L’état de l’art aujourd’hui

Au moment de l'écriture, le WebAssembly en version 1.0 est pratiquement entièrement pris en charge par les navigateurs modernes. Vous pouvez suivre l'avancement du standard et des disponibilités sur la roadmap du projet “https://webassembly.org/roadmap/”.

Le WebAssembly promet beaucoup :

Dans la réalité, les choses ne sont pas si belles. En grande partie parce que la technologie est jeune, mais on ne sait pas comment elle va évoluer.

Exécuter du code plus rapidement

En effet, le WASM permet d'exécuter du code plus rapidement, cependant on ne peut pas faire toutes les opérations possibles avec. Par exemple, on ne peut pas manipuler le DOM.

Quand on sait qu'aujourd'hui, un processeur passe la plupart de son temps en mode IDLE à attendre des instructions, avoir un langage plus rapide ne changera pas les performances dans tous les cas. D'autres standards du Web vont traiter ces problèmes de performance, comme le shadow DOM et les "Web Components". Mais les cas où l'utilisation du WebAssembly apportera un gain de performance considérable sont peu fréquents. On peut citer les jeux vidéo, la cryptographie, le calcul brut de données, l'intelligence artificielle et encore d'autres. Peut-être que le gain de performance apporté par le WebAssembly va amener de nouveaux usages.

ISO-fonctionnel

Cette promesse est presque atteinte. Au moment de l'écriture, Safari n'implémente pas une fonctionnalité du standard 1.0, mais cela n'empêche pas le fonctionnement du WebAssembly sur ce navigateur. Là où le support des navigateurs peut être un peu faible, c'est sur les débogueurs qui ne sont pas encore totalement au point et qui peuvent rendre la tâche un peu compliquée.

Multi-langage

Malgré le fait que le WASM soit destiné à la compilation, le support actuel des langages n'est pas parfait et aujourd'hui, beaucoup de langages restent indisponibles ou incomplets.

Les librairies

Les libraires peuvent tirer parti des fonctionnalités du WebAssembly. On peut citer QR2Text, qui permet de générer des QrCode et qui est plus performant que ses homologues en JavaScript (le bundle est plus petit). Cette librairie vient à l’origine d’un outil CLI fait en RUST et aucun changement dans le code n’a été nécessaire. D'autres frameworks, comme Flutter Web, utilisent le WebAssembly pour intégrer SKIA, un moteur de rendu qui permet d’afficher dans le web via le canvas une application Flutter.

image.png

Ressources

https://datareportal.com/reports/digital-2022-global-overview-report

https://www.youtube.com/watch?v=kCnYRhkfWHY

https://nostarch.com/art-webassembly

Fondamentaux

Comment ça marche

Dans cette partie, nous examinerons précisément les étapes pour passer du code source à son exécution en WebAssembly.

Étape 1 : Le code source

Dans un premier temps, nous devons écrire du code. Ce code peut être rédigé dans différents langages, à condition qu'ils soient compatibles avec un compilateur.

Il est également possible de partir d'un code existant, ce qui est plus fréquent lorsqu'on utilise C++, mais il est possible de le faire avec d'autres langages. Ces codes nécessitent généralement quelques adaptations, afin de se conformer aux contraintes des compilateurs.

Voici une liste non exhaustive des langages et leur maturité dans l'écosystème WebAssembly :

Les langages stables
Les langages embryonnaires
C# Elexir
AssemblyScript Java
C Javascript
C++ Kotlin
F# PHP
Go Python
Zig Ruby
Rust Swift
WAT Lisp

Étape 2 : La Compilation

Dans cette étape, nous allons utiliser un outil pour compiler notre code vers le WASM. Selon les cas, cet outil peut ajouter du code JavaScript qui entourera le code WebAssembly. Pour effectuer des actions qui sont aujourd'hui impossibles en WebAssembly, comme manipuler le DOM…

Certains compilateurs sont compatibles avec des interfaces de programmation. Par exemple, avec Emscripten, nous pouvons utiliser SDL et OpenGL.

Liste de compilateurs et des langages associés (liste non exhaustive) :

Compilateur Langage(s)
Wasm-Pack Rust
wat2wasm WAT
Emscripten C / C++
AsBuild AssemblyScript
Zig ZigLang
Blazor C# / F#
TinyGo Go

Nous avons énuméré les options les plus courantes, mais il existe parfois plusieurs manières de compiler du code source.

WASM Binaire

Une fois compilé, on se retrouve avec un ou des fichiers binaires. Ces fichiers ne sont pas lisibles par l'homme et contiennent les instructions du programme. Ces instructions, contrairement aux binaires classiques, ne sont pas destinées à des machines physiques, mais à des machines conceptuelles. C'est assez comparable au fonctionnement de la JVM. Une partie du travail est effectuée à la compilation, mais elle reste suffisamment floue pour pouvoir être interprétée par différentes architectures de processeur, différents navigateurs, etc.

Ce binaire est optimisé pour être rapide à charger, léger pour pouvoir être envoyé sur le réseau et pour s'exécuter dans un environnement isolé.

Interprétation

Une fois le fichier WASM créé, il ne nous reste plus qu'à l'exécuter. On peut le faire via un navigateur, mais il existe aussi d'autres solutions comme wasmtime ou des solutions cloud avec wasmedge et wasmer.

Ces solutions qui permettent d'exécuter du code WebAssembly côté serveur peuvent sembler contre-nature. Ne vous en faites pas, nous en reparlerons dans une section dédiée.

image.png

Fondamentaux

La suite de la formation

image.png

Vous êtes arrivé à la fin du module sur les fondamentaux. Nous avons vu comment le WebAssembly fonctionne, à quoi il peut servir et quels sont ses objectifs.

Dans ce module, nous avons seulement évoqué les concepts, car chaque langage et chaque compilateur a ses spécificités et nous les détaillerons au moment où nous les utiliserons.

Maintenant que vous avez ces bases, vous pouvez choisir une branche en fonction de vos affinités techniques qui vous permettra de développer vos compétences dans un domaine plus spécifique.

Domaines :

Navigateur Web

Navigateur Web

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 :

Nous allons aborder une approche intermédiaire, car nous allons utiliser AssemblyScript, un langage basé sur TypeScript conçu pour être compilé en WebAssembly.

image.png

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.

image.png

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 :

Sortie :

Débogage :

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 :

image.png

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.

image.png

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 :

image.png

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 :

image.png

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.

image.png

Exemple d’un ensemble de Mandlebrot

Grâce au projet disponible sur “https://github.com/ColinEberhardt/wasm-mandelbrot”, nous avons différentes implémentations de ce rendu, dont une en JavaScript pur et une en AssemblyScript, avec le minimum d'adaptation.

Si nous testons le calcul de rendu x10 (pour mettre à l'épreuve notre PC Patate), nous observons les résultats suivants :

image.png

Rendu de l’ensemble de Mandelbrot AssemblyScript

image.png

Rendu de l’ensemble de Mandelbrot JavaScript

Et là, surprise, aucune différence notable n'apparaît.

L'explication vient du fait que l'ensemble de Mandelbrot se génère par des calculs avec essentiellement des nombres à virgule flottante. Il se trouve qu'en JavaScript, le type number est un flottant et le JavaScript n'a aucune peine à faire des calculs sur ce type, car il est optimisé pour. Dans le cas d'AssemblyScript, comme le code utilisé est le même que celui en JavaScript avec le minimum d'adaptation, il n'y a pas de miracle : les opérations sur les nombres flottants en WebAssembly ne sont pas aussi optimisées.

Résultat : le JavaScript se débrouille mieux dans cette situation.

Il est possible de trouver des versions de l'ensemble de Mandelbrot plus performantes en AssemblyScript, si le code de ce dernier a été pensé pour le langage et n'est pas une simple "adaptation" d'un code existant dans un langage tel que JavaScript.

Tri des couleurs sur une image

Tournons-nous vers un autre projet, celui-ci : “https://github.com/manueldois/WebAssembly”.

Ce projet consiste à générer une image contenant des couleurs aléatoires, déterminées par une seed donnée. Le test de performance va consister à observer le temps que prend le programme pour trier chaque pixel de l’image afin d'obtenir un rendu comme celui ci-dessous :

image.png

image.png

La seed utilisée sera le mot “ESGI”, observons le temps que prend chaque implémentation pour trier les pixels de notre image :

image.png

Tri des couleurs en JavaScript

image.png

Tri des couleurs en AssemblyScript

Ici, le résultat est sans appel. L'implémentation en AssemblyScript est 4,5 fois plus rapide que celle en JavaScript.

Une image n'est, en fin de compte, qu'un tableau de pixels ayant une valeur représentant sa couleur. Le WebAssembly est tout à fait adapté à ce type d'utilisation.

Gestion des nombres et décalage de bits

Là où l'AssemblyScript se démarque, c'est dans la manipulation des nombres. En JavaScript, on utilise le type number, qui est un nombre à virgule flottante sur 64 bits, ou bien bigint (très rare).

En AssemblyScript, on a des types qui se calquent sur le WebAssembly, qui permettent de manipuler des nombres entiers sur 32, 64 bits, signés, non signés… (i32, u32, i64, u64…). Ces types sont bien gérés par le langage. On peut également utiliser des opérateurs logiques (bitwise operator).

Ce n'est pas quelque chose que l'on retrouve souvent dans du code métier, mais c'est un moyen d'optimiser son code. En JavaScript, cela fonctionne très mal (et c'est lent !)… La limitation vient du fait que cela ne fonctionne que sur les 32 premiers bits d'un nombre.

image.png

image.png

C'est juste inutilisable... À l'opposé de l'AssemblyScript qui gère ça très bien !

De nombreux algorithmes peuvent bénéficier de cette optimisation. Prenez l'exemple d'une IA.

Dans le cas d'un apprentissage d'un jeu d'échecs, il est possible de représenter en mémoire de manière très optimisée un échiquier, en utilisant les décalages de bits. On peut ainsi représenter l'état d'un échiquier avec seulement une douzaine d'entiers sur 64 bits.

Cette méthode s'appelle Bitboards. Vous pouvez trouver plus d'informations à ce sujet sur ce site : “https://www.chessprogramming.org/Bitboards

En utilisant ce principe, nous pouvons effectuer un benchmark pour calculer le nombre de coups possibles sur un échiquier après N tours.

Si nous jouons 5 tours, le nombre de possibilités s’élève à 4 865 609 ! Pour calculer cela, nous obtenons les résultats suivants :

CQFD.

Conclusion

AssemblyScript est super pour se mettre au WebAssembly, mais exige de revoir sa façon de coder pour obtenir des performances convaincantes et ne pas se contenter de « transposer » son code TypeScript en AssemblyScript. On y gagne rarement.

Il faut aussi savoir être pertinent ! Ce n'est pas parce qu'on va adapter son code (même bien) que cela sera forcément plus performant. Il faut bien étudier le besoin et ne pas hésiter à faire des benchmarks pour déterminer si le passage par le WebAssembly n'est pas une fausse bonne idée.

Ressources

assemblyscript.zip

https://www.assemblyscript.org/introduction.html

https://manueldois.github.io/WebAssembly/Sort Colors Benchmark/dist/index.html

youtube.com/watch?v=3KuDtqFxvRg

youtube.com/watch?v=gCT9ebtTzqw

youtube.com/watch?v=E0Z5oRq8APs

https://manueldois.github.io/WebAssembly/Sort Colors Benchmark/dist/index.html

https://colineberhardt.github.io/wasm-mandelbrot/#AssemblyScript

https://nischayv.github.io/as-benchmarks/graphics/fire/dist/index.html

https://www.chessprogramming.org/Bitboards

Navigateur Web

Framework Frontend

Comment lancer des applications Rust

Dans la vidéo suivante, nous allons utiliser des frameworks réalisés en Rust. Il est donc important d'installer le langage et d'en apprendre les bases. Attention, c'est un langage assez complexe. Ne vous inquiétez pas si vous ne comprenez pas tout : le compilateur vous expliquera vos erreurs lorsque vous écrirez du code.

Installer Rust

image.png

Ajouter la destination de compilation

Analysons le nom de cette destination de compilation :

À noter qu'il existe une destination de compilation wasm-wasi qui est utilisée par le projet wasmtime. Elle est un standard du WASI et est adaptée à l'exécution côté serveur d'applications 100% WebAssembly. Elle a la particularité de pouvoir compiler en créant plusieurs fichiers binaires, contrairement à wasm32-unknown-unknown.

Installer trunk

Trunk est un outil de gestion d'applications très répandu sur le web. Il permet de lancer et d'orchestrer des outils qui interviennent pendant la création d'un projet web, allant de la compilation de SASS à la compression d'image et à la compilation de fichiers Rust en WebAssembly.

Il existe plusieurs méthodes pour l'installer. Maintenant que vous avez installé Rust, je vous recommande d'utiliser Cargo, car cette commande fonctionnera quel que soit votre système d'exploitation et, étant donné que Trunk est un outil spécifique à Rust, il est logique qu'il soit désinstallé lorsque vous désinstallerez Rust.

image.png

Spécificité Mac

Pour les utilisateurs de la plateforme Apple Silicon, le module wasm bindgen-cli n'est pas installé correctement avec le tronc actuellement. Le paquet wasm bindgen est un outil qui permet de générer des liens (des ponts) entre le code Rust et du code JavaScript qui servira de connexion avec le navigateur.

La commande pour installer wasm bindgen-cli est la suivante :

image.png

Instruction spécifique a la version nightly

Il existe plusieurs versions de Rust, également appelées canaux de diffusion. Il y en a 3 principaux :

Rust ajoute des fonctionnalités en continu et n'a pas prévu de régressions. Il utilise le sémantique versionning. Aujourd'hui, aucun changement de version majeur n'est prévu.

La version stable de Rust est mise à jour toutes les 6 semaines. La version bêta représente la prochaine version stable.

Rust utilise une technique appelée "feature flag" pour déterminer si une fonctionnalité est active sur une version donnée. Si vous souhaitez utiliser les fonctionnalités non stables de Rust, vous devrez utiliser le canal Nightly et activer la fonctionnalité. C'est ce que fait le framework Leptos.

Commande pour installer le channel Nightly

image.png

Commande pour activer Rust Nightly

image.png

Commande pour lister les channels installées

image.png

Commande pour lister les channels installées

image.png

En vérité, on liste les toolchains, mais je ne vais pas faire la distinction entre toolchain et channel. 

Une fois passé à la version Nightly, je vous recommande de réinstaller la cible wasm32-unknown-unknown pour avoir la dernière version.

image.png

Démonstration

Type de rendu

Lors du développement d'une application frontend, il est important de prendre en compte ces différents enjeux lors du choix du type de rendu pour votre projet de développement afin de trouver l'équilibre approprié entre performance, charge sur les serveurs, répartition géographique des serveurs et SEO.

Le type de rendu désigne la façon dont les données sont présentées à l'utilisateur final, comment la page est construite et affichée. Il existe plusieurs solutions :

Le Client side rendering (CSR), dans lequel l'application est construite par le navigateur. Le serveur ne fait que renvoyer le code nécessaire au navigateur pour construire la page. C'est le code JavaScript qui va ensuite aller chercher la donnée et l'afficher dans la page.

Le Server side rendering (SSR) est un mode de rendu dans lequel le serveur va récupérer les données et construire la page avec ces données, puis l'envoyer au navigateur sous forme de package complet.

Le Static site generation (SSG) est le concept de générer des pages avec du rendu côté serveur pour des données peu souvent mises à jour, et de mettre ces pages en cache.

L'incremental static regeneration (ISR) est une forme de SSG dans laquelle on modifie les parties du cache sensibles aux changements plutôt que de régénérer tout le site.

Aujourd'hui, l'ISR est peu répandu et le CSR et le SSR ont des problèmes en termes de performance (SEO ou charge serveur). La génération d'un site statique est un processus qui peut être long, surtout si l'on veut construire des millions de pages. Heureusement, il existe Hugo (”https://gohugo.io/”) qui permet d'accélérer le processus de génération du site grâce à la gestion de la programmation concurrente du langage GO. Cependant, GO n'est pas un langage du web, et ici, on a dupliqué la manière de faire des rendus. Si cette logique pouvait être en WebAssembly, et donc disponible à la fois côté navigateur et côté serveur, on gagnerait énormément en performance et ouvrirait le web à de nouveaux usages. Pour cela, il faudrait néanmoins attendre que la gestion du DOM soit intégrée dans le WebAssembly. Ce qui n'est pas une priorité et qui risque de briser la nature du web et notamment la rétrocompatibilité. Cependant, peut-être verrons-nous arriver cette norme avec le HTML 7.

Ressources

https://docs.wasmtime.dev/wasm-rust.html

https://github.com/bytecodealliance/wasmtime/blob/main/docs/WASI-overview.md

https://github.com/rustwasm/team/issues/38

https://github.com/rustwasm/wasm-bindgen/issues/979

https://rust-lang.github.io/rustup/concepts/channels.html

Application côté Serveur

Application côté Serveur

Web Assembly & NodeJS

Problématique et objectif

De la même manière que le navigateur a des performances limitées, car le JavaScript n’est pas conçu pour cela, les applications back-end Node.js subissent le même problème (même si ce n'est pas toujours visible).

Une application backend Node.js aura du mal à supporter des charges ou des traitements lourds.

Nous allons explorer les solutions disponibles pour résoudre ce problème, car certaines librairies NodeJS utilisent déjà le WebAssembly afin d'améliorer les performances.

En effet, Node.js est tout à fait en mesure de prendre en charge des modules wasm : “https://nodejs.dev/en/learn/nodejs-with-webassembly/”.

Nous allons créer un outil permettant d’encoder et de compresser une vidéo en utilisant FFmpeg côté serveur.

FFmpeg.WASM

FFmpeg est une collection de programmes conçus pour effectuer des opérations sur des flux audio ou vidéo (enregistrement, lecture ou conversion d'un format à un autre). Cette bibliothèque est largement employée par d'autres applications ou services tels que VLC, iTunes, etc.

FFmpeg a été initialement écrit en C et C++, mais un portage WebAssembly existe sous la forme d'une librairie Node.js : “https://github.com/ffmpegwasm/ffmpeg.wasm”.

Prérequis

Pour suivre ce TP, vous devez avoir :

1. Mise en place

Nous allons créer un premier projet pour la partie serveur.

Créez un dossier ffmpeg-api et exécutez la commande suivante à l'intérieur :

image.png

Il faut ensuite installer les librairies dont nous aurons besoin avec la commande suivante :

image.png

Nous allons installer la définition des types nécessaires pour typescript

image.png

Pour automatiser le lancement de notre serveur, nous allons ajouter les scripts suivants dans le fichier package.json :

image.png

L’argument --experimental-wasm-threads permet au WebAssembly de gérer le multi-threading. C’est une fonctionnalité encore expérimentale et qui peut être instable.

Il ne nous manque plus que le fichier tsconfig.json à la racine du projet qui configure la façon dont TypeScript fonctionne.

image.png

2. Préparation du serveur express

Nous allons mettre en place la base pour notre serveur express en créant le fichier src/index.ts avec le code suivant :

image.png

Nous allons essayer cela, en lançant la commande suivante et en nous rendant sur le lien http://localhost:3000 :

image.png

image.png

image.png

Quand nous essayons d'atteindre notre page, nous obtenons le message Cannot GET /, ce qui signifie que notre serveur Express est bien en ligne. Il ne nous reste plus qu'à lui définir les routes dont nous aurons besoin prochainement.

3. Préparation du client web

Nous allons maintenant préparer la partie client, qui servira à envoyer la vidéo à convertir à notre serveur.

Dans un dossier à côté de celui de notre serveur ffmpeg-api, nous allons créer un nouveau dossier ffmpeg-client. Dans ce dossier, nous allons créer le fichier index.html avec le contenu suivant pour commencer :

image.png

Nous allons de ce pas créer le fichier client.js qui est importé par cette page, avec le contenu suivant :

image.png

Avec ce petit code, allons vérifier que notre client réagit comme on le souhaite lorsqu’on sélectionne un fichier vidéo.

image.png

Notre fichier est correctement chargé dans le navigateur, il nous reste simplement à l'envoyer au serveur et à récupérer le fichier vidéo retour.

Avant cela, nous allons faire quelques petits ajouts à ce fichier client.js pour y voir plus clair sur nos intentions.

image.png

4. Récupération de la vidéo côté serveur

Maintenant que tout est en place côté client, il faut que notre serveur Express puisse recevoir la vidéo, pour ensuite la convertir en utilisant la librairie FFmpeg en WebAssembly (qui est le but principal).

Il faut également s'assurer que le fichier reçu est bien un fichier vidéo, d'une taille raisonnable (comme le fichier sera stocké en mémoire, il vaut mieux qu'il ne dépasse pas un certain poids pour ne pas mettre le serveur à mal).

Nous allons utiliser le middleware "multer" évoqué plus tôt qui va nous permettre de définir une règle pour les fichiers envoyés via le format multipart requests.

image.png

Nous avons maintenant tout ce qu’il faut pour créer notre route /convert :

image.png

5. Conversion de la vidéo avec FFmpeg

Nous allons enfin pouvoir utiliser notre remarquable librairie en WebAssembly ! Elle était, à l'origine, pensée pour être exécutée côté navigateur, mais avec les versions les plus récentes de Node.js, c'est désormais possible sans problème.

Dans un premier temps, nous mettrons en place l'instance de FFmpeg afin de pouvoir l'utiliser au moment opportun :

image.png

Nous pouvons maintenant appeler cette fonction dans notre route convert :

image.png

Il faut ensuite donner à l’instance FFmpeg notre vidéo d’entrée pour que ce dernier puisse la traiter

image.png

Il ne nous reste plus qu’à lancer la commande FFmpeg avec les bons arguments afin de convertir notre vidéo ! Nous pouvons retrouver tous ces arguments sur la documentation officielle “https://trac.ffmpeg.org/wiki/Encode/H.264

image.png

Il faut alors attendre que l'encodage de la vidéo se termine... Selon le poids et la durée de la vidéo, cela peut prendre plus ou moins de temps.

Pour récupérer notre vidéo de sortie, nous allons à nouveau utiliser ffmpeg.FS pour lire les données du système de fichiers.

image.png

Nous pouvons ensuite supprimer notre fichier d’entrée et de sortie du contexte FFmpeg pour libérer de la mémoire.

Avec un peu de refacto, notre fichier final sera le suivant :

image.png

Voilà un exemple de conversion avec une célèbre vidéo :

image.png

image.png

image.png

6. Bonus : Gérer plusieurs demandes de conversion

Il n'est pas encore possible d'utiliser WebAssembly et Node.js pour traiter deux requêtes en parallèle (du moins, pas avec la librairie ffmpeg.wasm). La bibliothèque de threads WebAssembly a été introduite dans V8/Chrome depuis 2019. Cependant, cela reste encore expérimental dans Node.js et il faut activer le flag --experimental-wasm-threads pour l'utiliser.

Même si vous essayez (avec le flag) de lancer deux conversions simultanément, vous obtiendrez la sortie suivante :

image.png

Ne pouvant donc pas gérer plusieurs demandes en même temps, il est nécessaire de mettre en place un système de file d'attente afin d'éviter de faire planter notre serveur.

Pour cela, nous allons importer la librairie p-queue qui permet de créer des files d'attente concurrentielles.

image.png

Cela nous permet de créer une file d'attente concurrentielle de maximum un traitement à la fois.

Il suffit alors d'utiliser cette file au moment où nous devons encoder.

image.png

Récapitulatif

Ressources

wasm-ffmpeg.zip

https://www.secondstate.io/articles/getting-started-with-rust-function/

https://ffmpegwasm.netlify.app/

https://nodejs.dev/en/learn/nodejs-with-webassembly/

https://www.digitalocean.com/community/tutorials/how-to-build-a-media-processing-api-in-node-js-with-express-and-ffmpeg-wasm#prerequisites

https://trac.ffmpeg.org/wiki/Encode/H.264

https://www.ffmpeg.org/ffmpeg-filters.html

https://ffmpeg.org/ffmpeg.html

https://ffmpeg.org/documentation.html

https://jeromewu.github.io/ffmpeg-wasm-a-pure-webassembly-javascript-port-of-ffmpeg/

Application côté Serveur

WASI

Introduction

Pour l'exécution côté serveur, on entend bien sûr une exécution très éloignée du navigateur. Nous allons nous concentrer dans ce chapitre sur l'exécution en dehors de celui-ci.

Nous pouvons mettre en évidence deux méthodes d'exécution hors navigateur :

Nous parlerons de la spécification WASI, qui a pour objectif de rendre le WebAssembly un runtime portable, c'est-à-dire exécutable sur n'importe quel environnement.

Nous parlerons ensuite bien sûr de ces runtime qui respectent la spécification WASI et qui nous permettent de développer des applications serveur compilées en wasm.

WASI qu'est-ce que c'est ?

Tout d'abord, il est important de dire que les personnes travaillant sur les spécifications WASI sont un sous-groupe des personnes travaillant sur le WebAssembly; ce ne sont peut-être pas les mêmes personnes, mais elles gardent un contact étroit.

Les promesses de WASI seront les mêmes que celles du WASM :

Les fondations de cette spécification, d'un point de vue sécurité, font que les modules respectant les spécifications WASI ne peuvent pas :

WASI est une spécification qui permet d'accéder, en toute sécurité et en toute isolation, au système sur lequel tourne le module WASM.

Nous pouvons alors dire qu'un module WebAssembly s'exécute complètement isolé de la fonctionnalité native du système hôte sous-jacent. Cela signifie que, par défaut, les modules Wasm sont conçus pour effectuer uniquement des calculs purs.

En conséquence, l'accès aux ressources de niveau "OS" telles que les descripteurs de fichiers, les sockets réseau, l'horloge système et les nombres aléatoires n'est pas possible depuis WASM. Cependant, il existe de nombreux cas où un module Wasm doit faire plus que du calcul pur ; il doit interagir avec la fonctionnalité native de l’OS.

Nous constatons que pour créer et déployer des applications serveur, nous avons besoin d'un runtime qui respecte les spécifications WASI. Nous allons donc examiner en détail les trois plus populaires pour vous aider à mieux comprendre leurs avantages et inconvénients et à choisir celui qui convient le mieux à vos besoins.

WasmEdge

WasmEdge est un runtime WebAssembly léger, performant et extensible pour les applications cloud native, edge et décentralisées. Développé par Second State, il alimente les applications sans serveur, les fonctions embarquées, les microservices, les contrats intelligents et les appareils IoT.

Comparé aux conteneurs Linux, WasmEdge peut être jusqu'à 100 fois plus rapide au démarrage, 20% plus rapide à l'exécution et consommer jusqu'à 1/100 de la taille d'une application similaire en conteneur Linux. Cela signifie qu'il est possible de créer des applications plus rapides, plus légères et plus faciles à gérer. WasmEdge offre aux développeurs une plus grande flexibilité et des performances optimisées pour leurs applications, avec des temps de démarrage plus rapides et une consommation de mémoire réduite.

Ce runtime a été optimisé pour l'edge computing et ses principaux cas d'utilisation sont :

WasmEdge fournit également un ensemble d'extensions pour des cas d'utilisation plus avancés, tels que :

WasmEdge a également décidé d'implémenter le support des sockets en se basant sur la spécification actuelle des WASI-sockets.

Un autre avantage de WasmEdge est qu'il s'agit d'un projet sandbox officiel hébergé par la CNCF.

Wasmtime

Le premier avantage de ce runtime est qu'il est développé par la Bytecode Alliance, qui, comme vous le verrez, est une organisation composée de membres très compétents dans le domaine de l'informatique.

Il permet l'exécution du code WebAssembly en dehors du Web et peut être utilisé à la fois comme un utilitaire de ligne de commande ou comme une bibliothèque intégrée dans une application plus large.

Wasmtime prend en charge un riche ensemble d'API pour interagir avec l'environnement hôte via le standard WASI.

Wamstime utilise le compilateur Cranelift pour tous les cas d'utilisation, ce qui, par rapport à Wasmer, peut entraîner une perte de performance dans certains cas d'utilisation. N'oublions pas que, par rapport aux autres runtimes, celui-ci est développé par la Bytecode Alliance, qui ne tire aucun profit du projet.

Wasmer

La première version de Wasmer est sortie en 1 janvier 2021. D'un point de vue utilisation, Wasmer s'utilise comme une bibliothèque que l'on intègre dans n'importe quel langage de programmation supporté.

Wasmer vous permet d'exécuter des modules WebAssembly de manière autonome ou intégrée dans un grand nombre de langages. Wasmer est conçu pour fournir trois caractéristiques clés :

  1. Permettre aux programmes de s'exécuter dans n'importe quel langage de programmation.
  2. Permettre à des binaires extrêmement portables de fonctionner sans modification sur n'importe quel système d'exploitation.
  3. Agir comme un pont sécurisé pour les modules Wasm afin d'interagir avec les fonctionnalités natives du système d'exploitation, via des interfaces binaires d'application (ABI) telles que WASI.

Pour le premier cas, ils offrent des intégrations pour plusieurs langages, ce qui permet à un module Wasm d'être exécuté à partir de n'importe quel langage de programmation.

Pour le second cas, ils offrent leur Runtime autonome pour exécuter des binaires Wasm sur n'importe quelle plateforme et chipset.

Pour illustrer ses capacités, les développeurs de Wasmer ont compilé et exécuté une version non modifiée du serveur web Nginx, en utilisant des appels WASI pour interagir avec le système hôte.

Pour résumer les caractéristiques principales de Wasmer :

Gros point positif pour ce runtime : il met à disposition un gestionnaire de paquet nommé wapm qui est destiné à héberger des modules WebAssembly incluant des binaires et des bibliothèques universelles.

Bytecode alliance

Pour faire simple, WASM/WASI sont les spécifications du W3C et la Bytecode Alliance s'occupe de leur implémentation. La Bytecode Alliance est un projet visant à créer un environnement d'exécution multiplateforme et multipériphérique basé sur les avantages du WebAssembly. Ses membres fondateurs sont Mozilla, Fastly, Intel et Red Hat, et ils ont été rejoints par d'autres grands noms, tels qu'Amazon, ARM, Docker, Google, Microsoft et d'autres. Ils visent à créer de nouvelles fondations pour nos logiciels en se basant sur les standards WebAssembly et WebAssembly System Interface (WASI).

Les membres de cette alliance contribuent à plusieurs projets open source de l'alliance Bytecode, notamment :

Lequel choisir ?

Le choix va beaucoup dépendre de votre cas d'utilisation et de quand vous allez devoir le faire. En effet, le WebAssembly et encore plus le WASI sont des standards avec des implémentations très récentes. Il faudra donc effectuer un benchmark des performances des runtimes en fonction de vos besoins et des points clés de votre application.

Pourquoi utiliser un runtime serveur WASI plutôt qu’un runtime classique ?

Pourquoi ne pas toujours le faire si seuls des avantages en découlent ?

Aller plus loin

Ces runtimes ne sont bien évidemment pas seuls et certains runtimes beaucoup plus spécialisés sont apparus, nous vous laisserons jeter un coup d'œil si cela vous intéresse.

https://hacks.mozilla.org/2019/03/standardizing-wasi-a-webassembly-system-interface/

Ressources

https://wasi.dev/

Application côté Serveur

Serverless / Cloud

Partie 1

Partie 2

Ressources

https://github.com/suborbital/atmo

https://shopify.engineering/shopify-webassembly

https://workers.cloudflare.com/

https://www.infoq.com/presentations/wasm-server-api/?utm_source=youtube&utm_medium=link&utm_campaign=qcontalks

3D avec le Web Assembly

3D avec le Web Assembly

Unity Web & WebAssembly

Unity

Unity est un moteur de jeux vidéo multiplateforme qui fournit aux développeurs un éditeur.

Parmi les plateformes cibles supportées par Unity, le développeur peut choisir WebGL pour compiler une version web de son jeu.

Auparavant, Unity utilisait ASM.js pour transpiler le code du jeu en JavaScript, car c'était le moyen standard d'exécuter des instructions dans un navigateur. Depuis 2018, Unity se base sur le WebAssembly, car cette solution apporte un gain de performance et de nombreux avantages par rapport à ASM.js.

WASM vs ASM.js

Les performances sont similaires entre WASM et ASM.js, dans le cas où le navigateur est optimisé pour ASM.js. Ce qui rend WASM meilleur est son temps de démarrage plus rapide, car le JavaScript doit être parsé et interprété. De plus, la taille du binaire est réduite d'environ 10-15%, ce qui est significatif, car le fichier doit être téléchargé à chaque chargement de page s'il n'est pas mis en cache ou en cas de mise à jour.

Les deux solutions s'appuient sur les mêmes étapes et outils de compilation pour être compilées. Ainsi, le processus de compilation d'un jeu pour la plateforme web n'a pas beaucoup changé.

image.png

Démonstration

Nous allons partir d'un projet existant, puis définir le web comme plateforme cible et analyser la composition du build avec WASM sur Unity.

image.png

Afin de définir la plateforme cible, nous devons sur notre éditeur Unity :

  1. Aller dans le menu file et sélectionner l’option Build Settings… qui contient tous les paramètres relatifs à la création d’un livrable de notre jeu
  2. Ensuite, nous sélectionnons dans la liste des plateformes l'option WebGL pour créer une version WebAssembly de notre jeu.
  3. En cliquant sur le bouton Build, l'éditeur lancera les différentes étapes de construction.
  4. Et pour finir, nous sélectionnons le dossier dans lequel notre build sera situé.

image.png

Une fois le build effectué, on retrouve les fichiers suivants :

image.png

Dans le dossier build, nous retrouvons les fichiers suivants :

Ressources

Organisation d’un projet Unity

image.png

https://zenn.dev/okuoku/articles/5a7a04e75234b3

https://medium.com/wasmer/wasmer-io-devices-announcement-6f2a6fe23081

https://blog.unity.com/technology/webassembly-is-here

Intelligence Artificielle

Intelligence Artificielle

Tensorflow.JS

Tensorflow.js et le WebAssembly

Qu'est-ce que l'IA et le WebAssembly ?

L'arrivée du WebAssembly dans l'IA :

On peut dire que le WebAssembly a profondément pénétré le monde de l'IA le jour où TensorFlow.js a officiellement annoncé son support pour le WebAssembly en tant que backend alternatif à WebGL le 11 mars 2020.

Comment le WebAssembly peut-il aider l'IA ?

Le WebAssembly, et plus particulièrement l'IA dans les navigateurs, répond à différentes problématiques :

Rapidité :

Exécution rapide sur CPU.

Très utile pour les machines qui ne disposent pas d'un GPU performant ou même d'un GPU et donc pas d'une exécution via WebGL.

À noter que le WebAssembly est disponible sur la très grande majorité des navigateurs web.

Partage :

La possibilité d'exécuter l'apprentissage automatique dans les navigateurs, sans aucune installation supplémentaire.

Les modèles et les applications écrites sont faciles à partager sur le Web, ce qui réduit la barrière à l'entrée de l'apprentissage automatique.

Ceci est particulièrement important pour les cas d'utilisation éducative et pour augmenter la diversité des contributeurs dans le domaine.

Interactivité :

Du point de vue de l'apprentissage automatique, la nature interactive des navigateurs Web et les capacités polyvalentes des API Web ouvrent la voie à un large éventail de nouvelles applications d'apprentissage automatique centrées sur l'utilisateur, qui peuvent servir à la fois à l'enseignement et à la recherche.

Les visualisations de réseaux neuronaux peuvent ainsi être représentés ainsi :

image.png

https://playground.tensorflow.org/#activation=tanh&batchSize=10&dataset=circle&regDataset=reg-plane&learningRate=0.03&regularizationRate=0&noise=0&networkShape=3,2&seed=0.47115&showTestData=false&discretize=false&percTrainData=50&x=true&y=true&xTimesY=false&xSquared=false&ySquared=false&cosX=false&sinX=false&cosY=false&sinY=false&collectStats=false&problem=classification&initZero=false&hideText=false

Calcul local et sécurité :

L'accès normalisé à divers composants matériels du dispositif, tels que la caméra web, le microphone et l'accéléromètre, dans le navigateur, permet une intégration simple entre les modèles de ML et les données des capteurs.

Un résultat important de cette intégration est que les données de l'utilisateur peuvent rester sur le dispositif et préserver sa vie privée, ce qui permet des applications dans les domaines de la médecine, de l'accessibilité et du ML personnalisé.

Par exemple, les personnes souffrant de troubles de la parole peuvent utiliser leur téléphone pour recueillir des échantillons audio afin d'entraîner un modèle personnalisé dans le navigateur.

Une autre technologie pourrait permettre aux dispositifs d'entraîner de manière collaborative un modèle centralisé tout en conservant les données sensibles sur le dispositif.

Les navigateurs sont une plateforme naturelle pour ce type d'application.

Présentation de TensorFlow.js

Historique

TensorFlow a été développé en 2011 chez Google comme leur bibliothèque propriétaire pour les applications d'apprentissage automatique/apprentissage profond. Elle a été mise en open source en 2015 sous la licence Apache.

TensorFlow est construit en C++, ce qui permet au code de s'exécuter à un niveau très bas. Il est lié à différents langages tels que Python, R et Java, ce qui permet son utilisation dans ces langages.

Traditionnellement, en JavaScript, le ML/DL (Machine Learning / Deep Learning) était réalisé en utilisant une API. Une API était créée à l'aide d'un cadre quelconque, et le modèle était déployé sur le serveur. Le client envoie une requête en JavaScript pour obtenir les résultats du serveur.

En 2017, un projet appelé Deeplearn.js est apparu, qui visait à permettre le ML/DL en JavaScript, sans le besoin d'une API. Cependant, la question de la vitesse se posait. Le code JavaScript ne pouvait pas s'exécuter sur GPU. Pour résoudre ce problème, WebGL a été introduit. Il s'agit d'une interface de navigateur pour OpenGL, qui a permis l'exécution de code JavaScript sur GPU.

En mars 2018, l'équipe DeepLearn.js a fusionné avec l'équipe TensorFlow de Google et a été renommée TensorFlow.js.

Qu'est-ce que c'est ?

TensorFlow.js est une bibliothèque permettant de construire et d'exécuter des algorithmes d'apprentissage automatique en JavaScript. Les modèles TensorFlow.js s'exécutent dans un navigateur Web et dans l'environnement Node.js. La bibliothèque fait partie de l'écosystème TensorFlow, fournissant un ensemble d'API compatibles avec celles de Python, ce qui permet aux modèles d'être portés entre les écosystèmes Python et JavaScript.

TensorFlow.js a permis à un nouveau groupe de développeurs issus de la vaste communauté JavaScript de créer et de déployer des modèles d'apprentissage automatique et de mettre en place de nouvelles classes de calcul sur appareil.

TensorFlow.js permet :

TensorFlow.js fournit deux API :

JavaScript VS WebGL VS WebAssembly

Comparaison avec JavaScript

WASM est généralement beaucoup plus rapide que JavaScript pour les charges de travail numériques communes dans les tâches d'apprentissage machine. En outre, WASM peut être décodé nativement jusqu'à 20 fois plus rapidement que JavaScript.

JavaScript est typé dynamiquement et possède un garbage collector, ce qui peut causer des ralentissements non déterministes importants au moment de l'exécution. De plus, les bibliothèques JavaScript modernes (telles que TensorFlow.js) utilisent des outils de compilation tels que TypeScript et des transpileurs ES6 qui génèrent du code ES5 (pour une large prise en charge par les navigateurs) dont l'exécution est plus lente que celle du JavaScript ES6 classique. Le WASM utilise la bibliothèque XNNPack pour accélérer les opérations.

Comparaison avec WebGL

Il faut savoir que le WebGL peut être utilisé via le WebAssembly, donc ce ne sont pas forcément deux choses décorrélées. Néanmoins, on peut se demander si le WebGL utilisé avec du code JavaScript est plus rapide que le WebAssembly.

La réponse est comme pour beaucoup de choses en Informatique, ça dépend. Ça dépend de la taille du réseau de neurone à utiliser, mais cela dépend aussi du système d’exécution du processeur pour le WebAssembly.

Nous allons le voir plus tard, mais le SIMD et le multithreading ont véritablement apporté un coup de pouce au WebAssembly qui, sans cela, n'était pas capable d'égaler les performances du WebGL ou du WebGPU.

À noter que, si le WebAssembly est pris en charge par tous les principaux navigateurs, il ne dispose pas tous d'instructions SIMD.

Arrivée du SIMD

Qu'est-ce que le SIMD ?

Single Instruction on Multiple Data, ou SIMD, est l'un des quatre modes de fonctionnement définis par la taxinomie de Flynn et désigne un mode de fonctionnement des ordinateurs dotés de plusieurs unités de calcul en parallèle.

Dans ce mode, la même instruction est appliquée simultanément à plusieurs données pour produire plusieurs résultats.

On utilise cette abréviation par opposition à SISD (Single Instruction on Single Data), le fonctionnement traditionnel, et MIMD (Multiple Instructions on Multiple Data), le fonctionnement avec plusieurs processeurs indépendants. Le modèle SIMD convient particulièrement bien aux traitements dont la structure est très régulière, comme c'est le cas pour le calcul matriciel.

Ce calcul matriciel est à la base de nos modèles de Deep Learning et notamment des modèles de vision par ordinateur.

Les instructions SIMD ont été ajoutées aux processeurs modernes pour améliorer la vitesse de traitement des calculs impliquant des nombres en virgule flottante.

Le SIMD est souvent implémenté pour nous dans des bibliothèques hautes performances (comme OpenCV) et généré par notre compilateur lorsque nous compilons avec la vectorisation activée.

Cela se passe au niveau du processeur :

image.png

Analogie entre instruction unique / SIMD / Multithreading

Si nous faisons une analogie avec la préparation d'un repas, le SIMD revient à aligner tous nos haricots verts et à les couper en tranches en une seule fois.

L'instruction unique est la "tranche", les données multiples et répétées sont les haricots. En fait, l'alignement des données ("alignement de la mémoire") est un aspect important du SIMD.

Le multithreading, c'est comme si plusieurs chefs prenaient des ingrédients dans un garde-manger commun, les préparaient et les mettaient dans une grande marmite commune. Le travail est effectué plus rapidement car plusieurs chefs sont impliqués.

Arrivé du multithreading

Le multithreading désigne le fait d'avoir plusieurs fils d'exécution, normalement sur différents cœurs de processeur, en même temps. Il s'agit d'un niveau plus élevé que le SIMD et les threads existent généralement beaucoup plus longtemps.

Un thread peut acquérir des images, un autre peut détecter des objets, un autre peut suivre les objets et un dernier peut afficher les résultats.

Une caractéristique du multithreading est que les threads partagent tous le même espace d'adressage, de sorte que les données d'un thread peuvent être vues et manipulées par les autres. Cela rend les threads plus légers que les processus multiples, mais peut rendre le débogage plus difficile, par exemple lorsqu'un thread interfère avec un autre.

Les threads sont dits "légers" car leur création et leur démarrage prennent généralement moins de temps que ceux des processus complets.

Rien n'empêche une application d'utiliser à la fois le SIMD et le multithreading.

Pour revenir à l'analogie de la cuisine, vous pouvez avoir plusieurs chefs (multithreading) qui découpent tous leurs haricots verts de manière efficace (SIMD).

Cas pratique

Introduction

MobileNet

BlazeFace

 

Blockchain

Blockchain

L’écosystème blockchain et WebAssembly

Cette section est assez spécifique au monde de la blockchain, nous allons donc redéfinir certains termes.

Une blockchain est un réseau qui permet le partage de données sans intermédiaire. Techniquement, c'est une base de données distribuée.

Un nœud est une machine qui fait partie du réseau et qui héberge une copie de la base de données.

Dans les blockchains plus modernes, comme celles dont nous allons parler par la suite, il est possible d'utiliser la blockchain à la fois comme une base de données, mais aussi comme une puissance de calcul pour exécuter des programmes.

WebAssembly est une technologie très populaire dans le monde de la blockchain. Beaucoup de projets ont commencé, mais très peu sont matures.

Les objectifs d'une blockchain sont les suivants :

On se rend compte que ces objectifs sont alignés sur les objectifs du WASM qui sont :

Le seul souci est l'aspect déterministe : chaque blockchain qui a décidé de mettre l'accent sur le WebAssembly a dû résoudre d'une manière ou d'une autre ce problème.

Ethereum

Le projet Ethereum fonctionne sur la base d’une machine virtuelle appelée EVM. Cette machine permet de programmer en Solidity, un langage spécifiquement conçu pour le développement blockchain. Cependant, ce langage a des défauts qui limitent l'ouverture de la plateforme à une plus large communauté de développeurs. La fondation Ethereum souhaite donc utiliser une destination de compilation intermédiaire comme le WebAssembly.

Pour ce faire, la communauté Ethereum a travaillé à développer un sous-ensemble d’instructions qui soient totalement déterministes. Toutefois, ce projet de mise à jour a été mis en pause temporairement. Il est possible que les équipes du projet Ethereum reprennent le développement après la mise à jour de janvier 2023.

Comsos

COSMOS est un réseau de blockchain interopérable. Sa plateforme de machines virtuelles WebAssembly, COSMOWASM, a été lancée avec sa version 1.0 en juin 2022. Il s'agit du projet WebAssembly dans la blockchain le plus abouti.

La Fondation COSMOS recommande d'utiliser le langage Rust, car il est officiellement intégré dans l’écosystème COSMOS. AssemblyScript est en cours d'ajout à la liste des langages supportés par COSMOWASM, et le support complet devrait être disponible en 2023.

Polkadot

Polkadot est semblable à Cosmos, un réseau blockchain (qu'on appelle aussi une blockchain de layer 0). Ils expérimentent un système d'exécution de programme en WASM sur leur réseau "canary", appelé Kusama. Il s'agit d'un réseau en "bêta publique", où l'on peut tester nos programmes en WebAssembly. Malheureusement, le développement de ce réseau est en early-stage et il n'est pas recommandé pour une utilisation en production.

Elrond

L’écosystème blockchain et WebAssembly est dominé par Elrond. Elrond est une blockchain qui fait appel à wasmer comme moteur d’exécution. Malgré sa jeunesse et sa peu grande maturité, Elrond est la seule plateforme qui exécute des programmes basés sur le WebAssembly. Ces programmes peuvent être écrits dans n'importe quel langage qui peut être compilé en WASM.

La plateforme Elrond encourage le développement en Rust en raison de sa compatibilité avec l’écosystème.

Ressources

https://medium.com/@rauljordan/webassembly-the-future-of-blockchain-computing-1a0ae28f7e40

https://ewasm.readthedocs.io/en/mkdocs/

https://github.com/ewasm/design

https://github.com/openethereum/pwasm-tutorial

https://www.youtube.com/watch?v=2eISBAbT3GM

https://medium.com/nearprotocol/wasm-for-blockchain-2019-d093bfeb6133

https://wasmer.io/

https://medium.com/oasislabs/blockchain-flavored-wasi-50e3612b8eba

https://github.com/beriberikix/awesome-wasm-blockchain

Notions avancées

Notions avancées

Dynamic Linking

Le Dynamic Linking n’est pour le moment supporté que par LLVM, ainsi ce chapitre est réalisé en langage C++ avec le compilateur Emscripten.

Qu'est-ce que le Linking

Avant d'exploiter le Dynamic Linking avec le WebAssembly, nous allons tout d'abord commencer par comprendre ce qu’est le Linking de librairie, ainsi que les avantages et inconvénients de ces méthodes.

Le Static Linking consiste à empaqueter les différentes dépendances dont votre application a besoin dans un binaire unique, qui n’aura ainsi besoin d’aucune dépendance préalablement installer sur un système pour fonctionner. Ce genre de binaire est souvent appelé un binaire portable étant donné qu’il ne nécessite aucun fichier externe afin de démarrer. En contrepartie, on se retrouve très généralement avec un binaire qui pèse plutôt lourd et qui doit être remplacé lorsqu’on souhaite le mettre à jour.

Contrairement au Static Linking le Dynamic Linking permet quant à lui d’externaliser les différentes dépendances de l’application et de les joindre à l’application lors de son exécution. Dans de gros projets, on peut retrouver des fichiers avec l'extension .DLL (Dynamic Link Library), ce sont justement les librairies que l’application va intégrer au lancement. L’avantage principal de cette approche est la possibilité de remplacer unitairement les dépendances de l’application lorsqu’elles sont mises à jour. Mais cela est couteux en termes de performances et de temps de chargement lors de l’utilisation de l’application.

Et pour finir le Dynamic Loading qui permet de la même manière que le Dynamic Linking de séparer en plusieurs binaires notre application, mais il va nous permettre tout simplement de les charger au besoin. C’est potentiellement la méthode qui nous intéressera le plus étant donné qu’il permet d’alléger la charge réseau sur notre navigateur. Et le plus gros avantage est que l’application est prête à l’emploi avant même que nous ayons chargé toutes les dépendances. Ce qui nous permettra ainsi de d’abord charger le module principal, puis de charger de manière asynchrone les modules secondaire.

Dans le cas d’utilisation du WebAssembly, étant donné que le binaire doit être téléchargé depuis internet, le poids du binaire devient ainsi une préoccupation auxquelles, le Dynamic Linking peut être une solution.

Le Linking en WebAssembly

Maintenant qu’on a vu ce qu’est le Linking de librairie, voyons comment il s’applique au WebAssembly. Nous allons nous baser sur une application afin de voir ensemble comment mettre en place les différentes méthodes.

L’application sur laquelle nous allons nous baser consiste en un Main qui recense les différentes opérations de calcul que peut effectuer un utilisateur ainsi que les différents modules qui comporte la logique de ces opérations.

Static Linking

Étant donné que ce n’est pas l’objectif de ce chapitre, nous allons simplement voir dans cette section comment est constituée notre application de référence et faire un rappel sur Emscripten.

Composition du projet

Tout d’abord, voyons de quoi est composé le projet. On remarque deux choses, d’abord qu’il y a des fichiers .cpp qui servent pour notre application en WebAssembly.

image.png

On retrouve également un fichier « package.json » qui correspond au fichier de configuration d’un projet Node, celui-ci va nous aider à lancer la compilation de notre application.

image.png

Si on regarde dans le package.json, on retrouve la commande de compilation de notre WebAssembly qui va permettre après une réadaptation de changer notre méthode de Linking. On trouve aussi la commande serve qui sert à lancer un serveur HTTP permettant de servir les différents fichiers, ce qui peut être nécessaire étant donné que certains navigateurs ne peuvent accéder à des fichiers statiques qu’au travers d’un serveur.

Dans le fichier index.html, on retrouve notre affichage qui se présente sous la forme de deux entrées de texte, une dropdown pour choisir l’opérateur, un bouton égal et une zone d’affichage pour notre résultat.

image.png

Le fichier index.html est composé d’un module JavaScript qui se charge d’importer le fichier généré par le compilateur et de mettre à disposition du front, une fois notre module charger, l’instance de notre module ainsi que la fonction permettant de faire appel à notre module.

image.png

La fonction calculate est très simple, elle récupère les entrées utilisateur depuis le DOM, fait appel à notre fonction de calcul écrite en WebAssembly et affiche la valeur de retour à l’utilisateur.

image.png

Rappel Emscripten

Faisons un bref rappel de comment on utilise Emscripten avec la commande que l’on utilise pour notre application.

em++ --bind -s EXPORT_ES6=1 -o calculator.out.js src/modules/subtraction.cpp ./src/modules/addition.cpp src/calculator.cpp

Tout d’abord, il faut voir l’outil em++ comme un équivalent de g++ mais qui compile exclusivement nos fichiers sources pour du WASM. Donc pour compiler un binaire cela se passe de la même manière, on spécifie les fichiers qui doivent être compilé et on spécifie le fichier de sortie.

Il ne faut pas oublier de spécifier quelles fonctions on veut exporter ainsi que le nom par lequel on pourra les appeler dans notre code JavaScript. D’abord, on importe la librairie d’emscripten <emscripten/bind.h> puis comme sur l’image qui suit on spécifie la fonction que l’on veut exposer.

image.png

Dynamic Linking

Afin de lier nos modules à notre application, on va devoir faire appel aux arguments fournis par Emscripten, Si tout se passe bien, on ne devrait avoir à faire aucune modification dans notre code pour transformer en module WASM nos fichiers source.

Avant de commencer, veillez à garder la commande de compilation originale, car on va devoir la retravailler pour créer notre module principal.

Pour ce faire, on va d’abord commencer par déclarer les modules secondaires en séparant en plusieurs commandes pour chaque module que l’on va créer et en ajoutant l’argument qui désigne notre binaire WASM comme étant un module secondaire.

em++ -s SIDE_MODULE=1 ./src/modules/subtraction.cpp -o subtraction.out.wasm

em++ -s SIDE_MODULE=1 ./src/modules/addition.cpp -o addition.out.wasm

une fois les modules compilés avec les commandes précédentes, on va reprendre la commande originale et on va simplement déclarer que c’est devenu un module principale grâce à l’argument -s MAIN_MODULE=1 puis pour que le module sache quelle sont les librairies qu’il doit intégrer lors de l’initialisation, on doit définir les fichiers .wasm précédemment compiler dans notre commande.

On devrait se retrouver avec une commande tel que la suivante.

em++ --bind -s EXPORT_ES6=1 -s MAIN_MODULE=1 -o calculator.out.js src/calculator.cpp addition.wasm subtraction.wasm

Maintenant compilons le module principal et voyons ce qui se passe dans le navigateur.

image.png

On voit à présent que lors du chargement de la page, que tous nos fichiers WASM ont été téléchargés afin de lancer notre application.

Dynamic Loading

Nous allons désormais nous intéressez à la partie qui va nous permettre de réduire l’utilisation du réseau en téléchargeant nos modules au besoin.

Dans nos modules, nous allons déclarer les fonctions que l’on veut exporter avec l’instruction extern.

image.png

Contrairement au Dynamic Linking, on va devoir apporter des modifications à notre module principal. On va notamment faire usage de la fonction dlopen() cette fonction va nous permettre de remplacer nos instructions include et ainsi de chargé une fois appelé le module spécifié dans la fonction.

Étant donné que l’on doit retirer nos *include*, les signatures des fonctions doivent être définies dans notre module principal, autrement, on ne sait pas dans notre module principal comment nos fonctions doivent être appelé.

image.png

Dans le code suivant, nous faisons un appel à la fonction dlopen() et nous récupérons un pointeur sur un handle vers la librairie que nous venons de charger. Enfin, on récupère grâce à la fonction **dlsym()** l’adresse de notre fonction que l’on va cast avec la signature définie précédemment.

image.png

Une fois les modifications faites dans notre code, les commandes doivent être réadaptées pour le Dynamic Loading.

Dans nos commandes permettant de compiler les modules secondaires, il n’y a pas beaucoup de changements, seul l’argument -s EXPORT_ALL=1 est ajouté afin de permettre l’accès aux fonctions de ce module.

Pour ce qui est du module principal, on doit lui retirer les noms de nos modules qui permettaient d’indiquer, ils devaient être importés au lancement. Puis, nous allons ajouter à la place l’argument --preload-file qui prend soit un fichier ou bien un répertoire.

Il faut savoir que l’argument --preload-file permet d’empaqueter dans un fichier .data nos différents modules, ce qui les rend disponibles une fois le chargement du paquet terminé. Mais rien ne nous empêche d’implémenter notre propre moyen de chargement des modules en JavaScript.

Nous retrouvons donc la commande suivante, qui permet de compiler le module principal et de fournir tous les modules supplémentaires nécessaires pour le bon fonctionnement de l'application. En effet, si nous ne spécifions pas les modules à lier au lancement, la commande va les chercher et les charger au fur et à mesure des opérations. Cela nous permet d'avoir une application plus fluide et plus efficace.

em++ --bind -s EXPORT_ES6=1 -s MAIN_MODULE=1 -o calculator.out.js src/calculator.cpp --preload-file assets/modules

Ainsi que cette commande qui permet de compiler un de nos modules.

em++ -s SIDE_MODULE=1 -s EXPORT_ALL=1 ./src/modules/subtraction.cpp -o assets/modules/subtraction.out.so

Maintenant que notre projet est prêt, compilons le et voyons ce qui se passe :

image.png

On voit sur la capture d’écran que désormais les modules ne sont pas plus directement chargés et ont été remplacés par le fichier calculator.out.data

Ressources

wasm-calculator-dynamic-linking.rar

wasm-calculator-dynamic-loading.rar

wasm-calculator-static.rar

https://medium.com/@arora.aashish/webassembly-dynamic-linking-1644c9f40c8c

https://www.dynamsoft.com/codepool/webassembly-standalone-dynamic-linking-wasm.html

Notions avancées

Introduction au WAT

Le WAT (WebAssembly Text Format) est un format de fichier qui permet de représenter du code WebAssembly sous forme de texte humainement lisible. Sa syntaxe est issue des assembleurs classiques et utilise des mnémoniques pour représenter les instructions de WebAssembly. (func, module, import …)

Le WAT est principalement utilisé pour le développement et le débogage de code WebAssembly car il permet de lire et de modifier facilement le code source.

Il est aussi possible de se servir de WAT comme une destination de compilation pour pouvoir analyser les instructions utilisé.

Par exemple :

image.png

La commande a été faite avec WASM bindgen mais il est tout à fait possible de le faire avec d’autres outils.

Le WebAssembly Text Format (WAT) est un format ouvert et indépendant de la plateforme qui peut être compilé en binaire WebAssembly (.wasm) pour être exécuté dans un navigateur ou un environnement d'exécution WebAssembly. 

Il est important de noter que le WAT n'est pas un langage de programmation à part entière, mais plutôt un format de fichier pour représenter le code WebAssembly. Cependant, certaines librairies ou outils peuvent vous permettre d'écrire directement en WAT.

Le WAT présente des avantages pour le développement et le débogage, ainsi que pour l'apprentissage et la pédagogie. En utilisant le WAT, les étudiants et les développeurs débutants peuvent mieux comprendre comment fonctionne WebAssembly en étudiant le code source sous forme de texte. 

Le WAT permet par d’ailleurs une meilleure compréhension des instructions de WebAssembly et de leur utilisation, ce qui peut aider à améliorer la compréhension des concepts de bas niveau tels que la manipulation de la mémoire et les opérations de bas niveau.

Notions avancées

Docker et Wasm

Nous avions vu précédemment qu’aujourd’hui, l’utilisation du WebAssembly ne se limite plus qu’aux navigateurs et profite d’une utilisation également côté serveur, où dans le cloud…

Docker VS WebAssembly

Les débats autour de Docker et WebAssembly sont devenus de plus en plus intenses ces derniers temps. Certains pensent que le WebAssembly va remplacer Docker, ce qui n’est pas le cas.

Le WebAssembly et Docker sont des outils complémentaires, et non des outils concurrents. En effet, le WebAssembly ne remplace pas Docker, mais peut en fait être intégré à Docker pour rendre ses applications plus rapides et plus sûres.

Le WebAssembly peut offrir une meilleure sécurité et une vitesse d'exécution plus rapide et une image Docker plus légère. Cependant, le WebAssembly est encore une technologie relativement récente, et il y a encore des contraintes de sécurité et des difficultés de débogage à prendre en compte.

À l'avenir, nous pourrions voir une plus grande adoption des applications WebAssembly dans Docker, ainsi que des mises à jour permettant plus de sécurité et de facilité de débogage. Il est possible que nous commencions à voir des applications Docker-Compose multi-services basés sur le WebAssembly, ce qui pourrait offrir une solution à certains des problèmes de scalabilité et de sécurité rencontrés aujourd'hui.

Docker With WebAssembly

Aujourd'hui, nous ne devons plus penser que le WebAssembly peut remplacer Docker, mais au contraire, s'intégrer avec ce dernier.

Docker & Linux

Aujourd'hui, toutes les images Docker partent d'une base Linux. Cette dernière peut être plus ou moins légère, mais nous avons toujours cette couche supplémentaire d'un système d'exploitation, aussi léger soit-il, qui ralentit (un peu) le démarrage d'un conteneur et sa vitesse d'exécution.

Une nouvelle très bienvenue

Fin octobre 2022, une annonce officielle tombe. Celle de la prise en charge native du WASM dans Docker. Cette fonctionnalité n’est qu’au stade de BETA, mais cette annonce va amener des changements majeurs pour le futur de Docker.

Cette prise en charge native va permettre une vitesse d'exécution beaucoup plus rapide et une image Docker beaucoup plus légère. De plus, le WASM permet de s'affranchir de l'architecture serveur et offre une meilleure sécurité.

Docker WASM

Intérêt

Qu’est-ce que cela va apporter à Docker ?

Très utile donc dans un environnement Cloud qui nécessite du scaling très rapide, de la légèreté et vitesse de démarrage (coucou les lambda)

Cependant, l'utilisation de WebAssembly dans un environnement Docker est encore très limitée, car le WebAssembly est encore une technologie relativement récente. Il n'y a pas encore beaucoup de bibliothèques disponibles pour le WebAssembly, et les contraintes de sécurité sont toujours une préoccupation. De plus, il est encore très difficile de déboguer du code WebAssembly, ce qui est une tâche courante dans le développement logiciel.

Runner containerd

image.png

Le WebAssembly fonctionne dans Docker grâce au moteur d'exécution Runner containerd. Ce moteur est responsable de l'exécution des conteneurs et des microservices gérés par Docker. Il prend en charge plusieurs formats d'images, dont l'image WebAssembly, qui est compilée à partir du code source.

Une fois compilée, l'image WebAssembly est envoyée au moteur d'exécution Runner containerd, qui la charge et l'exécute.

Le runner WebAssembly actuel de Docker supporte wasm-edge, et pourrait supporter d'autres formats à l'avenir.

TD Énoncé

Ressources

https://docs.docker.com/desktop/wasm/

https://github.com/second-state/wasmedge-containers-examples/blob/main/http_server_wasi_app.md

https://nigelpoulton.com/getting-started-with-docker-and-wasm/

image.png

image.png

TD - Correction

TD - Performances & Comparaison

Conclusion

Le WebAssembly offre un grand nombre d’avantages pour l’utilisation de Docker. Il permet une vitesse d'exécution plus rapide, des images Docker plus légères et de s'affranchir de l'architecture serveur. Néanmoins, le WebAssembly est encore une technologie relativement récente, et il y a encore des contraintes de sécurité et des difficultés de débogage à prendre en compte.

À l'avenir, nous pourrions voir une plus grande adoption des applications WebAssembly dans Docker, ainsi que des mises à jour permettant plus de sécurité et de facilité de débogage. Il est possible que nous commencions à voir des applications Docker-Compose multi-services basés sur le WebAssembly, ce qui pourrait offrir une solution à certains des problèmes de scalabilité et de sécurité rencontrés aujourd'hui.

Ressources

todolist-rust-mysql-linux.zip

todolist-rust-mysql-wasm.zip

todolist-rust-mysql performances.zip

https://thenewstack.io/when-webassembly-replaces-docker/

https://www.programmez.com/actualites/webassembly-integre-dans-docker-preversion-34570

https://www.youtube.com/watch?v=9JVV2qrp080

https://techcrunch.com/2022/10/24/docker-launches-a-first-preview-of-its-webassembly-support/?guce_referrer=YW5kcm9pZC1hcHA6Ly9jb20uZ29vZ2xlLmFuZHJvaWQuZ29vZ2xlcXVpY2tzZWFyY2hib3gv&guce_referrer_sig=AQAAACCiX71P1TpECiG4S7K4MZJhVEzhfEzieZqCXtiIepBnMPEPumRydxLFPmA-N0bXv7iersP3wh28LIU3VB1Qn9oXd8d5B6FH1GJTrXUhTjIRZDl0tW3a80BvHd4TcFGT0DFkDAmt5Iq4dxRJYknQe9lYCwZDHIbaxRyj5P4nR7G3&guccounter=2

https://docs.docker.com/desktop/wasm/

https://github.com/second-state/wasmedge-containers-examples/blob/main/http_server_wasi_app.md

https://nigelpoulton.com/getting-started-with-docker-and-wasm/

https://docs.docker.com/desktop/wasm/

 

Notions avancées

Exécutions parallèles avec SIMD

Le SIMD (Single Instruction Multiple Data), qui fait partie de la topologie de Flynn, permet d'exécuter des instructions sur plusieurs données simultanément, ce qui améliore considérablement les performances des traitements. Il est très utilisé pour les traitements multimédias, comme la modification des pixels d'images ou le traitement de flux audio, et est particulièrement efficace pour les traitements nécessitant un grand nombre de données à traiter en même temps.

WebAssembly prend en charge les instructions SIMD sur 128 bits, mais rencontre des difficultés lorsqu'il s'agit de s'adapter à différentes architectures de processeur. Par exemple, sur l'architecture ARM, l'optimisation ARM NEON permet d'utiliser des registres de taille plus petite, ce qui accélère considérablement les accès. Cependant, avec l'arrivée de webGPU, ces problèmes sont moins préoccupants, car les traitements multimédias lourds peuvent être déplacés vers la carte graphique, ce qui permet d'obtenir des performances optimales.

En conclusion, le SIMD offre une puissance de traitement considérable pour les traitements multimédias, et WebAssembly permet de le faire fonctionner sur de nombreuses architectures, avec les optimisations nécessaires. Avec l'arrivée d'API telles que webGPU, la puissance de traitement peut encore être améliorée, ce qui permet d'obtenir des performances optimales pour les traitements lourds.

Conclusion

Au cours de ce cours, nous avons exploré plusieurs applications possibles du WebAssembly, aussi bien dans le navigateur que sur le serveur / le cloud. Ce que nous pensions être une simple technologie visant à améliorer les performances du navigateur, là où le JavaScript atteignait ses limites, s'est avéré avoir un potentiel encore plus grand.

Le WebAssembly offre une solution novatrice à des applications variées. Cela permet de résoudre des défis classiques et d'améliorer le rendement et la sécurité des systèmes, notamment dans des domaines tels que la blockchain, les serveurs, les frontends et le serverless. La technologie a été conçue pour être open source, ce qui facilite son adoption par les entreprises.

Le WebAssembly est un outil très prometteur qui est maintenant largement adopté par les développeurs. De plus en plus de développeurs comprennent les avantages qu'il offre et voient le WebAssembly comme un formidable outil. Ses bénéfices sont nombreux, surtout pour les développeurs qui peuvent créer des applications plus rapides, plus sûres et plus performantes.

Le WebAssembly présente également des avantages pour les développeurs qui travaillent dans un environnement cloud. En effet, cette technologie permet aux développeurs de tirer parti des avantages du cloud computing, sans avoir à s'inquiéter des restrictions des technologies traditionnelles. Cela facilite le développement et réduit les coûts.

Attention tout de même, il ne faut pas aller vers une utilisation excessive de cette technologie. Il faut garder en tête que le WebAssembly est encore jeune, et que les outils pour l'exploiter le sont aussi. Il faut donc être patient et bien cadrer son besoin, afin de déterminer si le WebAssembly va y répondre ou si des solutions plus traditionnelles valent mieux d'être utilisées encore un moment.

Enfin, le WebAssembly a beaucoup de potentiel et des possibilités infinies. Avec un nombre croissant d'outils et de technologies développés, le WebAssembly peut offrir des avantages encore plus grands aux développeurs et aux entreprises. En particulier, le WebAssembly peut aider à améliorer la sécurité, la qualité et la rapidité des applications Web et permettre des expériences plus riches et plus fluides pour les utilisateurs. Il est alors crucial que les développeurs continuent à explorer et à tirer parti des avantages du WebAssembly.

En somme, le WebAssembly offre de nombreux avantages aux développeurs et aux entreprises et est en train de devenir une technologie de plus en plus populaire et puissante. Les développeurs peuvent en tirer parti et profiter de ses avantages dans divers secteurs, tels que les serveurs, les frontends, le serverless et la blockchain. De plus, le WebAssembly a un grand potentiel pour l'avenir et les développeurs devraient continuer à explorer ses avantages.