Svelte.js : le compilateur qui s'attaque à React et Vue

Lors d'un code camp (l'YGLF 2019), le créateur de Svelte - Rich Harris - a salué React. Tout en expliquant pourquoi selon lui React et plus particulièrement son recours au virtual DOM était très inefficace. De bonne guerre lorsque l'on souhaite imposer sa nouvelle librairie/compilateur. Après tout, les ingénieurs en charge du développement de React ont eu également eu cette approche directe vis-à-vis de leurs concurrents d'alors en 2013.

Le virtual DOM serait trop lent

D'après Rich Harris, les ingénieurs de React reconnaissent eux-mêmes que le virtual DOM est trop lent, puisque :

  • ils ont mis à disposition un life cycle hook tel que shouldComponentUpdate

  • ils ont créé des abstractions telles que React.PureComponent, useMemo ou useCallback, qui vous permettent de dire à votre application de ne pas tenir compte d'un sub-tree de votre application.

  • React donne désormais la possibilité de recourir à un "concurrent mode"

Tout cela sonnerait comme un aveu que le virtual DOM n'est pas assez performant alors que ce même virtual DOM était mis en avant pour ses performances (par rapport au DOM "réel").

Performances ET "declarative framework"

D'après Rich Harris, les frameworks organisent nos esprits plutôt que notre code. Un framework devrait uniquement intervenir durant le build de nos applications. Autrement dit, le compilateur devrait s'imposer afin de réduire l'emprise des frameworks sur nos développements.

La philosophie de Svelte

Elle peut se résumer ainsi : prendre des composants développés dans un style déclaratif ("declarative components") et en faire du code imperatif bas niveau qui manipulera le DOM directement.
Le problème qui a occupé les créateurs de React ou Vue s'est ainsi posé à Rich Harris : comment détecter un changement, ce fameux changement qui provoque un nouveau rendu de la vue d'un composant ?


inscrivez vous à la newsletter de meanjs.fr


Nouveau mode de détection du changement

Au commencement (toujours dans le cas de React), la methode this.setState() avait la responsabilité de fusionner ancien state et nouveau state puis de déclencher un nouveau rendu de votre component. De nos jours, depuis fin 2018, les React hooks prennent la relève.
Aussi, dans ses premières versions, Svelte avait marché sur les traces de React en utilisant this.set() au lieu de ... this.setState(). Et s'est encombré du fameux problème de 'this' en JavaScript (comme dit la boutade : "fuck this but wait, what is 'this'").
Pour dire à un ordinateur qu'un changement a eu lieu, un opérateur est utilisé (notre bon vieux opérateur "="). Ou encore, comme le fait Vue.js, on peut détecter le changement d'une variable en créant des propriétés via la propriété data de l'objet passé à une instance de Vue({})

Svelte 3 : la réactivité est désormais dans le langage lui-même

Avec la toute nouvelle mouture de Svelte - la v3 - la réactivité se déplace des APIs des components vers le langage lui-même. Charge au compilateur de détecter ce qui a changé (en l'invalidant) afin que ce changement soit pris en compte par l'event loop.

Le JavaScript dans le HTML ...

... Plutôt que du HTML dans JavaScript. Rich Harris revendique cette inversion. Ceci afin de compiler en fonction de ses besoins spécifiques,par exemple pour du SSR (Server Side Rendering).

Moins de tuyauterie à implémenter par le développeur

Si React permet, grâce à useMemo(), de comparer la valeur d'une variable dans le temps afin d'éviter un rendu superflu du composent, Svelte dispense le développeur d'implémenter un équivalent de useMemo() en ajoutant lui-même le code permettant de déterminer si une variable a été modifiée.

40% de code en moins en Svelte qu'en React

En convertissant de nombreux composants écrit en React en composants Svelte, Rich Harris déclare un résultat d'environ 40% de lignes de code de moins avec Svelte. Quant on sait que Svelte cible IoT et autre wearables, ce n'est pas anodin (plus de détails plus bas dans ce post).

S'inspirer de D3.js afin de rendre une variable "observable"

Rich Harris s'est également inspiré du travail de Mike Bostock, le créateur de D3.js. Et plus particulièrement du "topological ordering" cher à Mike Boston, qui incite à prioritairement évaluer une valeur B dont dépend une valeur A du fait précisément que A dépende de B.

Rendre une variable reactive à l'aide de "$:"

Ce symbole (un dollar suivi de deux points) permet, en JavaScript, de lier une variable à une autre. Autrement dit, "$:" permet de rendre "reactive" une variable afin qu'un changement de ladite variable occasionne un nouveau rendu de la vue du component.
Rich Harris pousse plus loin l'idée d'Evan You - le créateur de Vue.js - qui avait popularisé le fait qu'en JavaSript, un assignement de variable ait des side-effects désirables. Rich Harris déplace cette "magie" du navigateur vers le compilateur. Pour Rich Harris, l'important est la fonctionalité recherchée, pas l'endroit où elle existe.

Amélioration des performances

Rich Harris n'a pas résisté à la publication d'un benchmark montrant que Svelte est 35 fois plus rapide que React et 50 fois plus rapide que Vue. Bon, les benchmarks sont parfois tirés par les cheveux. Mais tout comme les statistiques, on se sert de celles qui confortent notre point de vue :)

Améliorations des performances (suite)

Plusieurs stratégies sont depuis longtemps utilisées afin d'améliorer les performances de nos applications web et mobiles. Le fameux debouncing, bien connu lorsque dans le cas d'un champ texte : on retarde le traitement aussi longtemps qu'un utilisateur est en train de taper du texte. Après par exemple 100ms d'arrêt de frappe, le traitement commence. Cela évite de multiples traitements intermédiaires. Le seul défaut du débouncing est l'absence de feedback.
L'autre approche est le "concurrent mode" que propose désormais React.
La voie qu' a choisie Rich Harris est plus radicale. Il considère en effet qu'il vaut mieux ... ne pas avoir de frameworks (ou de librairies) introduisant des problèmes de performances qu'il faut alors corriger, que de se consacrer à la résolution de problèmes introduits par les librairies et frameworks. Il compare son approche à celle adoptée par les constructeurs de voitures électriques : plutôt que d'améliorer des moteurs thermiques aux centaines de pièces (certes génialement associées), opter pour un moteur n'ayant que deux partie mobiles. L'approche de Rich Harris se veut clairement disruptive.

Ok, mais Svelte est-il utilisé dans la "vraie" vie ?

Au Brésil, l'entreprise Stone a doté ses 200000 terminaux de paiement mobile d'une interface graphique créée à l'aide de Svelte. Elle avait ainsi constaté une bien meilleure expérience utilisateur qu'avec React, Vue ou de nombreux autres librairies et frameworks.
Idem pour l'entreprise russe Mustlab et ses smart TV.

La nouvelle frontière : le web embarqué

Wearable, IoT, smart TV, écrans de contrôle dans les voitures ou les smart homes etc... est d'après Rich Harris la nouvelle frontière des développeurs. D'où l'importance capitale accordée aux performances. Ce n'est ainsi plus le plaisir de gagner un benchmark qui est mis en avant mais bien des performances boostées au service d'une expérience utilisateur améliorée sur des devices portables amenés à se multiplier.

Accessibilité

Rich Harris tient à ce que les développeurs utilisant Svelte.js pensent aux utilisateurs qui ont un handicap nécessitant d'utiliser des screen readers. Des warnings apparaissent donc pour vous signifier que votre code ne prend pas en compte certains devices.

Directives d'animation

Svelte permet de créer des animations grâce au package 'svelte-transitions'. Les animations de Svelte se basent sur des animations CSS car elles sont plus performances et moins énergivore pour la batterie des devices que des animations créées en JavaScript.
Le fait que Svelte soit un compilateur lève la contrainte de la taille du package dédié aux animations. La présence native de ce package d'animations n'impactera pas la taille du bundle si vous décidez de ne pas utiliser d'animations. Cela fait partie de la philosophie de Svelte de découpler les fonctionnalités proposées de la taille des fichiers générés.

CSS

Svelte propose des "scoped styles" (comme le fait Vue.js), qui permettent de ne pas voir le style d'un composant poluer le style d'autres composants de votre applications.
En outre, Svelte permet la détection de styles CSS non utilisés, afin de permettre précisément de supprimer des styles CSS non utilisés lors de la compilation. Adieu la crainte de supprimer du CSS de peur qu'il soit utilisé quelque part.

Sapper : le Next.js ou Gatsby de Svelte

Svelte est un compilateur permettant de créer des composants bas niveau pour des applications pouvant aller jusqu'à une complexité intermédiaire. Passé une certaine complexité, Svelte propose "Sapper" qui vise à concurrencer Next ou Gatsby de l'univers React. Sapper fournit routage, code splitting et SSR (Server Side Rendering) tous deux automatiques etc...

Svelte Native

La communauté Svelte propose le projet "Svelte Native" basé sur nativescript-vue afin de permettre la création d'applications iOS et Android à l'aide de Svelte.

Svelte GL

Enfin, Svelte GL est l'équivalent Svelte de Three.js.

En résumé

Svelte :

  • c'est du "compile-time black magic" afin de déplacer vers le compilateur ce qui se passe d'ordinaire dans les APIs de vos composants
  • se positionne sur le développement d'applications performantes
  • cible les programmeurs professionnel mais paradoxalement aussi les amateurs qui connaissent un peu le HTML et souhaitent jouer avec sur de petits projets.

Cet article de blog est tiré de cette présentation (en anglais) :
https://www.youtube.com/watch?v=AdNJ3fydeao

L'ouverture d'esprit de Rich Harris apparait clairement dans cette conférence. Même s'il aime adopter une posture un peu provocante à l'égard de React ou Vue, il le fait avec humour, sans agressivité ni revanche à prendre. Il connait bien les champions qu'il défie et cherche à s'attaquer aux faiblesses de ses concurrents. Après tout, un framework fait toujours des compromis.

Sa stratégie de communication consiste à bousculer le status quo qui limite le paysage des frameworks et librairies JavaScript à React, Angular et Vue, les autres - comme Ember et Aurelia - restant loin derrière en termes d'adoption (notamment en nombre d'offres d'emploi) malgré leurs qualités.

En attendant, si vous avez du temps de cerveau disponible, vous pouvez commencez à jeter un oeil à Svelte ... tout en continuant à miser sur React et Vue - les deux concurrents que le créateur de Svelte cite (pour ne pas dire "cible") régulièrement - sans oublier Angular. En effet les ingénieurs de React, Vue et Angular ne restent pas bras croisés et ont bien conscience des améliorations à apporter à leurs frameworks et librairies. Ils ont eux aussi amélioré considérablement les performances des applications crées avec leurs frameworks et librairies (grâce au lazy-loading, tree shaking et autres SSR), à diminuer la taille des builds et continuent à proposer des évolutions majeures. C'est la raison pour laquelle Svelte a peu de chances de "tuer" ses concurrents. On est plutôt dans le jeu théâtral auxquels se livrent des boxeurs avant un match. Pour filer la métaphore, Svelte boxe d'ailleurs clairement dans la même catégorie que ses concurrents.
Dans un premier temps, ma boule de cristal me dit que Svelte pourrait se créer une quatrième marche de podium d'ici 1 à 2 ans. Plus sérieusement, le fait que Svelte apparaisse dans de plus en plus de newsletters et de tweets de grosses pointures JavaScript (tels qu'Evan You, Dan Abramov ou Ben Lesh) n'est pas anodin et peut laisser présager un destin.
Avec Stencil.js qui est lui aussi un compilateur, on voit peut-être se confirmer le grand retour des compilateurs, dans l'univers du développement web cette fois.
En tous cas, en ce mois d'avril 2019, s'intéresser à Svelte permet d'ores et déjà de découvrir, écouter et lire un créateur de compilateur très intéressant. C'est déjà un bon point. L'autre bon point est que si vous connaissez une ou plusieurs librairies JavaScript (telles que Vue et React), vous vous sentirez rapidement en terrain connu (props, events, observables etc ... sont de la partie).

Liens utiles

https://v3.svelte.technology
https://twitter.com/sveltejs
https://twitter.com/rich_harris

Article fortement recommandé par Rich Harris (en anglais) "What is reactive programming"
http://paulstovell.com/blog/reactive-programming