Cadres en voie de disparition

Pourquoi utilisons-nous des cadres? Angular, React et Vue nous aident à créer des applications Web complexes: structurer le code, gérer l'état et développer des interfaces complexes. Au cours de la dernière décennie, les cadres sont devenus la norme. Un standard cher. Depuis que les frameworks sont entrés en service, JS a été très gonflé. Il y a plus de pages pesant plusieurs mégaoctets, et une partie importante de ce volume est le cadre lui-même. Cela semble un peu, mais pour l'utilisateur, c'est critique - au téléphone ou sur Internet faible, la page peut même ne pas se charger. C'est un problème.



En plus d'être en surpoids, les cadres classiques présentent de nombreux autres inconvénients et ne conviennent pas à tous les projets. Ces problèmes sont résolus dans des «cadres menacés». Quelle est cette nouvelle tendance, pourquoi n'est-elle pas «un autre framework JS», mais une bonne idée et comment des frameworks mystérieux peuvent améliorer nos applications, dira Pavel Malyshev.

À propos de l'orateur: Pavel Malyshev ( PaulMaly ) - fullstack avec plus de 10 ans d'expérience. Il travaille chez Mustlab, qui sous-traite le Web, la Smart TV et les appareils mobiles, ainsi que l'IoT. Un évangéliste du cadre Svelte JS en Russie, dirige un groupe Telegram sur ce sujet.



Ce qui ne devrait pas figurer dans le rapport


Quand j'ai considéré cette histoire, j'ai décidé qu'elle devrait être non standard. Par conséquent, j'ai écrit ce qui ne devrait pas être ici. On ne mettra pas l'accent sur un cadre spécifique, des comparaisons avec d'autres cadres - ils sont fatigués de tout le monde et, bien sûr, je ne veux pas être le capitaine Obvious. Tout cela n'aurait pas dû être dans mon histoire, mais, malheureusement, ce sera ...

Lorsque vous avez lu le nom, vous avez probablement pensé qu'il y avait un autre cadre et qu'il y avait déjà tout un zoo.



Il me semble que si un nouveau cadre apparaît, alors les anciens ne satisfont pas certains de nos besoins. Peut-être que les besoins eux-mêmes changent avec le temps, et c'est pourquoi nous avons besoin de nouvelles solutions - plus efficaces et plus intéressantes. Par conséquent, je vous demande d'aborder ce qui précède de ce point de vue avec un esprit ouvert et de considérer les cadres disparaissants comme un nouvel outil qui peut vous aider dans votre travail.

Pour commencer, découvrons qui est qui.

Qui est qui


J'ai pris les trois grands et Svelte. Il est intéressant de noter que chaque outil se caractérise différemment. Angular se positionne comme un cadre pour toutes les occasions, «tout dans une boîte». React imite une bibliothèque: «Je suis aussi petite qu'une bibliothèque», mais avec toute l'infrastructure, c'est aussi un cadre à part entière. Vue est censé être un framework progressif. Vous pouvez y basculer avec jQuery en transférant séquentiellement le code, en commençant presque par la balise de script habituelle sans collecteurs. Svelte est un cadre qui disparaît comme par magie. Wat?

Voyons de quoi je parle.

Pourquoi les cadres ont-ils commencé à disparaître?


Nous envoyons trop de code à nos utilisateurs.

Nos clients deviennent de plus en plus mobiles, mais la technologie Internet n'est pas bonne partout - même la 3G n'est pas partout, sans parler du LTE. Nous devons réduire la taille du code.

Il y a une étude intéressante de 2017 sur ce sujet, qui montre que si votre application a beaucoup de JS, vous ne pouvez mettre que 130 Ko pour faire plaisir à l'utilisateur . Si JS est petit, alors jusqu'à 170 Ko. Cette différence est due au fait que l'étude a tenu compte du fait que JS est différent des autres types de ressources, il doit être analysé, interprété, etc.



Dans l'étude, 130 Ko n'est pas seulement JS, mais en général tout, y compris CSS, HTML, bien sûr, sans images. Dans le même temps, un Angular pèse 143 Ko, et nous n'avons même pas écrit une seule ligne de code. Voyons quelles solutions actuelles nous offrent.

Performances


En principe, tout framework classique est une abstraction sur une plateforme qui nous permet d'écrire à des niveaux plus pratiques. C'est mauvais car toute abstraction a des coûts, y compris les performances.

Nous encourons des coûts supplémentaires en raison d'abstractions inutiles entre notre code et le navigateur.

La caractéristique de la disparition des frameworks est qu'ils suppriment les abstractions et les calculs inutiles du moteur d'exécution du navigateur , effectuant des analyses et des calculs au moment de la compilation. C’est pourquoi ils disparaissent. Nous en parlerons plus en détail ci-dessous.

La compatibilité


Les solutions écrites pour le framework classique ne peuvent être appliquées nulle part.

Ils ne fonctionnent que dans le cadre de ce cadre. Par exemple, vous effectuez 2-3 projets sur votre React préféré, écrivez un tas de solutions intéressantes pour celui-ci, puis décidez de passer à Angular. Vous n'avez plus besoin de ces solutions, vous pouvez les jeter. Bien que l'idée centrale soit la mise en correspondance des composants, les frameworks classiques nous empêchent de réutiliser le code.

La chose à propos de la disparition des frameworks est qu'ils n'ont pas d'abstractions , et dans ce cas il n'y a pas de framework en runtime. Votre code est absolument vanilla JS, qui peut être utilisé n'importe où - dans n'importe quel projet, même sur un framework différent. Par exemple, vous pouvez prendre le code sur un framework qui disparaît et le transférer vers React.

Fractionnement de code et tremblement d'arbre


Les anciennes technologies rendent difficile l'application de nouvelles technologies.

La plupart des cadres ont été créés lorsque ces technologies n'ont pas été développées de la sorte. Nous avons un noyau assez monolithique et tout composant, même le plus petit morceau de votre code, est lié à l'ensemble du framework. Par conséquent, il n'est pas possible de diviser le code efficacement et même de secouer les arbres.

Désormais, tous les frameworks évoluent vers une plus grande modularité afin de mieux "secouer". Dans les frameworks qui disparaissent, cela est résolu dès le départ, car ils sont faits de telle manière que seul le code dont vous avez besoin au départ est ajouté au bundle , et cela résout votre tâche exclusivement. C'est un cas très spécifique - comme si vous avez écrit le code avec vos mains exactement pour votre tâche et que vous l'avez mis dans le bundle, seul le framework le fait pour vous.

Coût de la fonctionnalité


Tout cadre a un prix pour une nouvelle fonctionnalité.

La communauté a besoin de nouvelles fonctionnalités différentes et chaque membre a besoin de quelque chose qui lui est propre, et toute fonctionnalité a un prix. Dans les frameworks en voie de disparition, ce problème est résolu au niveau du concept, car toute fonctionnalité que vous n'utilisez pas n'entrera jamais dans votre bundle.
Donc, la question principale: les frameworks en voie de disparition, et spécifiquement Svelte, peuvent-ils résoudre tous ces problèmes? Faisons les choses correctement.

Bez avec runtime


Rantime est un sujet plutôt éphémère. Ce n’est pas clair, et différentes personnes le comprennent différemment. Dans ce contexte, je parlerai du runtime du point de vue de deux aspects: l' environnement dans lequel le code est exécuté et le code lui-même .

Le runtime comme environnement


Regardons un exemple. Si le code est écrit en Vanilla, alors le seul runtime nécessaire est le DOM. Si le code est écrit dans React, vous avez besoin d'un autre runtime: DOM, React et React DOM.

Dans tous les cas, le plus petit composant de votre code dans React dépend de l'environnement dans lequel votre framework fonctionne, c'est-à-dire lors de l'exécution.


Runtime comme exécution de code


Le deuxième point est l'exécution en termes d'exécution de code lors de l'exécution. Examinons le cas d'exécution de base d'aujourd'hui pour le frontend - le DOM virtuel - un gros morceau d'exécution, par exemple, dans les applications React - en utilisant un exemple simple:

 <h1>Hello {world}</h1> 

Il y a une variable dynamique dans ce morceau de HTML. Du point de vue du DOM virtuel, le code fonctionne ainsi.

  • Cette variable est en cours de modification.
  • L'arborescence DOM virtuelle en mémoire est en cours de construction.
  • Par rapport à la version précédente.
  • Les manipulations DOM sont effectuées directement, ce qui en fin de compte est assez efficace, car nous avons obtenu une sorte de différence et nous savons exactement quoi changer dans le vrai DOM.



Un DOM virtuel est un surcoût absolu, car il sera toujours plus rapide comme ceci: dès que des changements sont survenus, ils ont immédiatement apporté des modifications au DOM.



Question: comment comprendre ce qui a changé et ce qui doit être changé? Le DOM virtuel résout le problème de ce qui a changé, pas la vitesse de ces changements. La vitesse est atteinte grâce au fait que nous savons autant que possible ce qui a changé et que nous pouvons manipuler efficacement le DOM.

Compilez-le


Pour résoudre ce problème, les frameworks qui disparaissent déterminent simplement les changements au stade de la compilation: vous avez écrit le code, lors de la compilation, le framework qui disparaît crée toutes les dépendances, calcule quelles manipulations dans le DOM sont nécessaires. En fait, tout ce qu'un DOM virtuel fait en runtime, un framework de fuite le fait en temps de construction: il génère des manipulations directes avec le DOM, qui sont simplement appelées pendant le runtime. Le résultat est un diagramme: lorsque nous apportons des modifications, la manipulation dans le DOM va tout de suite.

Vous ne pouvez pas écrire d'applications sérieuses en JavaScript vanille sans heurter un mur de complexité. Mais un compilateur peut le faire pour vous.
Rich Harris, créateur de Svelte

Je vais vous raconter comment j'ai rencontré Svelte. Nous avions un projet intéressant - un widget à insérer sur un nombre illimité de sites, alors que nous ne savons pas de quels sites il s'agit, sur quels appareils l'utilisateur les ouvrira. Le widget doit être de très petite taille et très rapide. Naturellement, lorsque nous avons entrepris cette tâche, nous avons immédiatement compris que faire sur React ou même sur Vue n'est pas une option, car il se révèle beaucoup de frais supplémentaires.

Nous étions presque enclins à écrire en Vanilla, mais c'est difficile et pas toujours pratique à entretenir. Mais nous avons eu de la chance - nous sommes tombés sur Svelte. L'idée principale de ce cadre est donnée dans une citation: vous ne pouvez pas écrire une application sérieuse sur Vanilla, car vous rencontrerez rapidement un mur de complexité - il sera difficile pour l'équipe de travailler, il n'y a pas d'approches communes et le compilateur peut le faire pour vous.

Comment ça marche




Le code source est un code basé sur le framework - un code qui dépend du framework. Tout est comme d'habitude: il y a de la documentation, vous écrivez le code comme si vous utilisiez un autre framework qui a une sorte d'API, des principes et des approches. Tout est comme d'habitude.

Au moment de la construction, ce code se compile. En conséquence, vanilla JS se trouve dans le bundle, et, comme je l'ai dit, le code nécessaire à l'exécution de votre application y arrive précisément. Si, dans deux minutes, vous y ajoutez une nouvelle fonction ou utilisez une nouvelle fonctionnalité du framework, Svelte l'ajoutera là, et elle entrera également dans le bundle. Sinon, cela ne se produira pas.

Examinons les étapes plus en détail. La première étape est le composant . Considérez le même composant.

 <h1>Hello {world}</h1> 

Dans la deuxième étape - AST - le code est produit dans un arbre de syntaxe abstraite.

 {"type": "Element", "name": "h1", "children": [{ "type": "Text", "data": "Hello",....}]} 

La troisième étape est l' API DOM . Sur la base de l'arborescence, le code est généré directement, ce qui est nécessaire pour que ce composant fonctionne. Le code est très simple, il n'y a pas d'exécutions et d'abstractions compliquées ici en principe.

 function update(changed, ctx) { if (changed.name) { text_1.data = ctx.name; } } 

A la fin de l'article, indiquez dans l'enquête si vous aimez l'idée d'une compilation AOT du framework Svelte? La dernière fois, la majorité s'est exprimée positivement.



Voyons maintenant ce qu'est Svelte.

Svelte


Le mot anglais svelte ou svelt signifie «mince, flexible». Svelte JS l'est!

Je prétends que ce n'est pas «encore un autre framework JS» car c'est un framework d'interface utilisateur au moment de la construction . Les frameworks réguliers fonctionnent en runtime, et Svelte n'existe qu'avant que nous ne le compilions.

Il s'agit d'un analyseur statique au moment de la compilation ou d'un analyseur de code statique qui passe à travers le code pendant la compilation, l'analyse statiquement et, sur cette base, génère le bundle final correspondant.

Il s'agit d'un compilateur à l'avance - un compilateur AOT qui fait tout.

Le créateur du framework Rich Harris, que vous pouvez connaître à partir d'outils tels que Rollup, Ractive, Buble - un analogue de Babel - est un mec cool. À mon avis, le même Rollup est toujours la meilleure implémentation d'arborescence. Il y est apparu beaucoup plus tôt que dans Webpack et fonctionne toujours mieux. Harris a initialement construit le framework Svelte avec des arborescences, le fractionnement de code et d'autres approches modernes.

Svelte est un outil pour écrire JS vanille sans avoir à écrire JS vanille.

Regardons ce cadre de l'intérieur.

Composant de fichier unique


Svelte est un composant à fichier unique . Si vous avez travaillé avec Vue, cela vous rappellera beaucoup ce framework, mais ce n'est pas un hasard. La syntaxe que Vue utilise principalement est dérivée du cadre Ractive, que Harris a également créé en 2012. Ce framework, malheureusement, n'est pas devenu populaire, il me semble, car il est sorti trop tard en 1.0. Ils étaient tellement en désordre avec les versions que Ractive était en versions mineures depuis 6 ans.

Vue a emprunté de nombreuses interfaces à partir de là, et Svelte est le successeur de Ractive. Par conséquent, il vous semblera que tout est similaire, mais des composants à fichier unique sont apparus dans Ractive en 2013. Ils ont l'air un peu différents, mais dans l'ensemble - ça a l'air. Tout composant que vous écrivez dans Svelte ressemblera à ceci.

 <h1 >Hello {world}!</h1 > <script> export default { /* component behaviour */ }; </script> <style>    /* scoped styles */ </style> 

Ci-dessus est un certain modèle HTML - HTML simple sans aucune exception. La seule chose en plus est un certain langage de modèle appelé HTMLx . Je vous en dirai plus sur lui plus tard.

Vient ensuite le script dans lequel nous écrivons le comportement de notre composant. Comment l'écrire est décrit dans le guide. Là, vous pouvez importer, créer diverses fonctions et méthodes - tout comme dans Vue.

Vous pouvez utiliser un style limité pour obtenir des styles de composants isolés dans la boîte. Cela fonctionne comme ceci: dans la compilation principale, un hachage est généré, par conséquent, c'est comme émuler un DOM Shadow.

Aucune des sections n'est requise, donc un composant ne peut être composé que d'un seul HTML.

Syntaxe HTMLx


Comme pour tout HTML, les données sont écrites entre parenthèses.

 <button>Say hello {name}</button> 

C'est ainsi que les instructions conditionnelles sont écrites.

 {#if name} <button>Say hello {name}</button> {/if} 

Énumérations et boucles:
 {#each users as { name, email}} {#if name} <button>Say hello {name}</button> {/if} {/each} 

Vous pouvez utiliser des directives pour intercepter des événements, pour une double liaison de données.

 {#each users as { name, email}} {#if name} <button on:click="say(name)">Say hello {name}<button> {/if} {/each} 

Il y a très peu de directives dans HTMLx - seulement 4-5 types, et il n'y a pas de directives personnalisées, comme dans Angular.

Vous pouvez insérer n'importe quelle donnée dynamique dans n'importe quel attribut, cela ne pose aucun problème.

 <div id= "{dynamic}"class="used"> {#each users as { name, email}} {#if name} <button on:click="say(name) " >Say hello {name}<button> {/if} {/each} </div> 

Styles isolés et suppression des éléments inutilisés


Si vous utilisez des styles isolés, en plus d'être isolés, les styles inutilisés sont également coupés automatiquement.

 <div id= "{dynamic}"class="used"> {#each users as { name, email}} {#if name} <button on:click="say(name) " >Say hello {name}<button> {/if} {/each} </div> </style> .used {...} .unused {...} </style> 

Si le style est used , alors il est utilisé, et si le style n'est unused , il ne sera pas dans le bundle. Le cadre coupera tout, mais proprement. Par conséquent, cette fonctionnalité peut être facilement interrompue si vous utilisez beaucoup de dynamique. Svelte pensera: «Je ferais mieux de ne pas toucher» - et partir. Il faut être prudent, mais c'est très pratique. Étant donné que Svelte possède un analyseur statique, il affiche dans la console au démarrage les styles qui ne sont pas utilisés. Si vous n'en avez vraiment pas besoin, vous pouvez les retirer immédiatement.

Composition des composants


Tout est comme d'habitude ici: nous importons le fichier, l'enregistrons dans les composants, nous l'utilisons comme tag.

 <Nested foo= "static" bar={dynamic} bind:baz=baz /> <script> import Nested from 'Nested.html';' export default {   components: {Nested} }; </script> 

Vous pouvez transférer toutes les données via les attributs, utilisez la double liaison. Ou ne pas utiliser - la double liaison est facultative, elle peut même être désactivée au niveau du compilateur, et elle ne sera nulle part ailleurs. C'est pour ceux qui n'aiment pas les fixations. Les liaisons sont obtenues à l'aide de la directive bind: :.

Fonctionnalités supplémentaires de Svelte


Les deux premières possibilités sont les suivantes: SSR & Hydration - rendu et hydratation du serveur, et gestion d'état intégrée - gestion d'état globale intégrée basée sur notre propre solution, la soi-disant magasin.

En principe, vous pouvez utiliser Redux, ce que beaucoup font: ceux qui ont l'habitude de Redux l'utilisent avec Svelte. Mais il existe une solution interne plus simple qui est profondément intégrée de sorte que si vous l'enregistrez dans le magasin, elle est immédiatement disponible dans toutes les hiérarchies de composants - aucune manipulation du tout. La seule chose à utiliser est d'utiliser le préfixe $ , c'est-à-dire que toutes les méthodes ou les données de stockage sont écrites avec ce préfixe. $ peut être utilisé dans n'importe quel modèle.

Le magasin a une fonctionnalité intéressante que je n'ai vu nulle part ailleurs - il s'étend globalement à une hiérarchie de composants. Si vous avez, par exemple, un composant racine, il est utilisé dans toute cette hiérarchie. Si vous avez un autre magasin quelque part dans cette hiérarchie, ce magasin s'étend à toute la hiérarchie inférieure.

Ceci est pratique lorsque vous souhaitez créer un grand composant complexe avec de nombreux sous-composants, puis l'utiliser dans différents projets, dont certains sont Redux et d'autres non. Si vous utilisez des magasins réguliers avec Redux, vous devez vous assurer que le projet où vous l'ajoutez a Redux. Cela n'a pas besoin d'être fait ici - Svelte implémente son propre magasin pour cette hiérarchie. Il peut être facilement transféré même vers les projets où il n'y a pas de magasin mondial du tout. Vous l'avez apporté, et Svelte fait déjà tout à l'intérieur.

Les éléments personnalisés sont pris en charge prêts à l'emploi . Il existe un site spécial sur lequel le support est testé par des frameworks de la norme Web Components. Selon les tests, Svelte prend en charge à 100% les éléments personnalisés. Cela fonctionne comme ceci: le nom de la balise est spécifié, l'indicateur «customElement: true» est défini dans le compilateur et un élément personnalisé prêt à l'emploi est généré qui prend en charge toutes les fonctionnalités Svelte existantes.

Sapeur - Créateur d'applications Svelte . Il s'agit d'un analogue de Next.js et Nuxt.js pour Vue. En principe, tout est identique: isomorphisme, prise en charge du fractionnement de code, de la prélecture et hors ligne, ainsi que d'autres fonctionnalités. À mon avis, récemment, même certaines des idées de routage sont venues de Sapeur à Next.js.

Mais aucun Svelte ne le fait. Nous sommes pour une concurrence loyale!

Qui d'autre?


Stencil est un framework des développeurs Ionic. Ils travaillent également sur un cadre compilé, mais avec un accent particulier sur les composants Web et les éléments personnalisés. Svelte en diffère par le fait que ses composants sont généralement compilés en classes JS régulières et qu'il n'y a pas de biais dans les composants Web.

Glimmer - Je pense que tout le monde connaît ce projet. Il n'est présenté ici que parce qu'il compile aussi: il a son propre bytecode, sa propre machine virtuelle, ce qui donne évidemment des optimisations supplémentaires pour le code final.

Marko d'eBay . Je ne l'ai pas étudié en détail, mais ils compilent également, pas sûr de ce qui est aussi profond que Svelte. Certes, je n'ai pas compris en détail et je peux me tromper.

Angulaire Il y a un compilateur AOT ici, et il sera bien promu, mais ce n'est qu'une recompilation de modèles de chaînes sous une forme triée prête à l'emploi à l'avance. Pour autant que je sache, il n'y a pas encore de compilation AoT complète.

Bonjour les films


J'ai écrit une petite application - une liste de films avec des filtres basés sur l'API TMDb. Il a des catégories: populaires, les mieux notées, à venir. Vous pouvez parcourir les pages, sélectionner un pays, lui appliquer des filtres, changer la langue. Cette application primitive ne prend que 6,4 Ko.

Au total, HELLO MOVIES ne compte que 172 lignes de code avec HTML, dont 36 lignes de code JS, avec toutes sortes de citations. C'est tout le code que j'ai écrit personnellement. Naturellement, tout cela se compile pour un volume beaucoup plus important, mais pour moi, en tant que développeur, cela n'a pas d'importance.

Encore quelques indicateurs. "TodoList MVC" sur Svelte prend 3,6 Ko - cela dépend de qui il dit, mais même sur Vanilla, il prend 11 Ko, et sur Vue et React encore plus - 80 et 300 Ko, respectivement. Le projet "RealWorld", un clone de Medium, avec inscription, comptes, likes, partages, amis - 40 Ko, sur React et Angular - 211 et 575 Ko. Le clone de "HackerNews" sur Svelte est de 30 Ko, sur React et Vue - plusieurs fois de plus.

Repères


Nous aimons tous hollichivat sur le thème des repères. J'ai utilisé le célèbre benchmark Krausest . Vous pensez probablement que je vais maintenant montrer les résultats où Svelte déchire tout le monde en lambeaux et Inferno pleure juste de côté. Mais cela n'arrivera pas.



J'ai pris une comparaison de Svelte avec les Big Three - Angular, React et Vue dans les versions récentes. En conséquence, il a identifié les deux premières positions concernant la vanille. Et ici, les chiffres ne sont pas aussi importants que l'idée principale, à savoir que Svelte est très équilibré .

Svelte s'efforce d'être équilibré - il est bon à tous égards dans toutes les références . À certains égards, Svelte dépasse même Vanilla, dans certains cas, il prend le premier, mais quelque part il dépasse Vue et Angular. Cependant, dans tous les tests, Angular et Vue consomment beaucoup de mémoire, mais Svelte ne le fait pas. , , . — .

Svelte — . , .

- — !


Svelte New York Times. . , Svelte, , legacy- CMS, . , , .



, - « » — , Drag&Drop. Svelte, .

Soft-Gear , , Svelte. , - .

airca.st Svelte. Dabble Svelte. - i-want-to-ride-an-electric-citi Svelte.

. , RuTube. Smart TV Tizen, Samsung. Tizen Smart TV Svelte. , .





standalone vanilla JavaScript . , , overhead .

. Svelte DOM. .

. , Vue, Svelte . , REPL , , .

. , — , . , .

Code-splitting & tree-shaking . code-splitting tree-shaking. . , .

Micro-frontends ready . -. , , PHP, Svelte-. , . , . code-splitting tree-shaking.



Svelte , . 2016 . .

. , . . , , , , , Vue.

. React Facebook, Angular — Google, Vue , Rich Harris , .

Frontend Conf ++ , , . 33 . ++ 27 28 .

Source: https://habr.com/ru/post/fr450822/


All Articles