L’hydratation JavaScript est une solution de contournement, pas une solution

Dans le développement Web, l’hydratation est une technique permettant d’ajouter une interaction au code HTML rendu par le serveur. C’est une technique dans laquelle JavaScript côté client convertit une page Web HTML statique en une page Web dynamique en attachant des gestionnaires d’événements aux éléments HTML.

Cependant, attacher des gestionnaires d’événements au modèle d’objet de document (DOM) n’est pas la partie la plus difficile ou la plus coûteuse de l’hydratation.

Dans cet article, j’expliquerai pourquoi je crois que l’hydratation est un frais généraux. Ce n’est pas la solution; c’est un hack qui consomme de la mémoire et ralentit le démarrage, surtout sur mobile. Pour les besoins de cet article, définissons les frais généraux comme un travail qui peut être évité et conduit toujours au même résultat final.

Approfondir l’hydratation

Miško Hevery

Miško Hevery est le directeur de la technologie chez Builder.io. En tant que CTO, Miško supervise la division technologique qui alimente les applications et logiciels Builder.io. Avant de rejoindre Builder.io, il a créé des plateformes open source pour Google, notamment Angular et AngularJS, et a été co-créateur de Karma. Chez Google, il y a apporté une culture de test avec son blog. Avant de se concentrer sur l’amélioration du Web, il pense que les tests sont la clé du succès.

La partie difficile de l’hydratation est de savoir de quels gestionnaires d’événements nous avons besoin et où ils doivent être attachés.

  • QUEL: Le gestionnaire d’événements est une fermeture qui contient le comportement de l’événement. C’est ce qui devrait arriver si un utilisateur déclenche cet événement.
  • : L’emplacement de l’élément DOM où le WHAT doit être attaché (inclut le type d’événement)

La complication supplémentaire est que QU’EST-CE qu’une fermeture qui se referme APP_STATE et FW_STATE:

  • APP_STATE: l’état de l’application. APP_STATE est ce que la plupart des gens considèrent comme l’État. Sans pour autant APP_STATEvotre application n’a rien de dynamique à montrer à l’utilisateur.
  • FW_STATE: l’état interne du framework. Sans pour autant FW_STATE, le framework ne sait pas quels nœuds DOM mettre à jour ou quand le framework doit les mettre à jour. Les exemples sont l’arborescence des composants et les références aux fonctions de rendu.

Alors, comment récupérer QUOI et OÙ ? En téléchargeant et en exécutant les composants rendus en HTML. C’est la partie la plus chère.

En d’autres termes, l’hydratation est un hack pour récupérer le APP_STATE et FW_STATE en exécutant avidement le code de l’application dans le navigateur et implique :

  • Téléchargement du code du composant.
  • Exécution du code du composant.
  • Récupération du QUOI (APP_STATE et FW_STATE) et WHERE pour obtenir la fermeture du gestionnaire d’événements.
  • Attacher WHAT (la fermeture du gestionnaire d’événements) à WHERE (un élément DOM).

Appelons les trois premières étapes la phase de récupération.

Récupération est lorsque le framework essaie de reconstruire l’application. La reconstruction est coûteuse car elle nécessite le téléchargement et l’exécution du code de l’application.

La récupération est directement proportionnelle à la complexité de la page à hydrater et peut facilement prendre 10 secondes sur un appareil mobile. Étant donné que la récupération est la partie la plus coûteuse, la plupart des applications ont des performances de démarrage sous-optimales, en particulier sur mobile.

La récupération est également une surcharge : elle reconstruit les informations que le serveur a déjà recueillies dans le cadre du rendu côté serveur (SSR) ou de la génération de site statique (SSG). Au lieu d’envoyer les informations au client, les informations ont été supprimées. Par conséquent, le client doit effectuer une récupération coûteuse pour reconstruire ce que le serveur avait déjà. Si seulement le serveur avait sérialisé les informations et les avait envoyées au client avec HTML, la récupération aurait pu être évitée. Les informations sérialisées éviteraient au client de télécharger et d’exécuter avec impatience tous les composants du HTML.

En d’autres termes, la ré-exécution du code sur le client que le serveur a déjà exécuté dans le cadre de SSR/SSG est ce qui rend l’hydratation pure surcharge.

Capacité de reprise : une alternative sans frais généraux à l’hydratation

Pour supprimer les frais généraux, le cadre doit non seulement éviter la récupération, mais également la quatrième étape ci-dessus : attacher le QUOI à OÙ.

Pour éviter ce coût, vous avez besoin de trois choses :

  • Toutes les informations requises sérialisées dans le cadre du code HTML, y compris QUOI, OÙ, APP_STATEet FW_STATE.
  • Un gestionnaire d’événements global qui s’appuie sur le bouillonnement d’événements pour intercepter tous les événements afin que nous ne soyons pas obligés d’enregistrer avec impatience tous les événements individuellement sur des éléments DOM spécifiques.
  • Une fonction d’usine qui peut récupérer paresseusement le gestionnaire d’événements (le QUOI).

La configuration ci-dessus peut être reprise car elle peut reprendre l’exécution là où le serveur l’a laissée sans refaire le travail déjà effectué par le serveur. En créant le WHAT paresseusement en réponse à un événement utilisateur, nous pouvons éviter de faire tout le travail inutile qui se produit dans l’hydratation. Tout cela signifie pas de frais généraux.

Utilisation de la mémoire

Les éléments DOM conservent les gestionnaires d’événements pendant toute la durée de vie de l’élément. L’hydratation crée avec empressement tous les écouteurs, elle a donc besoin de mémoire pour être affectée au démarrage.

D’autre part, les frameworks avec reprise ne créent les gestionnaires d’événements qu’après le déclenchement de l’événement. Par conséquent, ils consommeront moins de mémoire que l’hydratation. De plus, le gestionnaire d’événements est libéré après son exécution, rendant la mémoire.

D’une certaine manière, libérer la mémoire est le contraire de l’hydratation. C’est comme si le cadre hydratait paresseusement un QUOI spécifique, l’exécutait puis le déshydratait. Il n’y a pas beaucoup de différence entre la première et la nième exécution du gestionnaire.

La différence de performances

Pour mettre cette idée en pratique, nous avons construit Qwik, un framework conçu autour de la « possibilité de reprise » et permettant un démarrage rapide. Pour vous montrer l’impact de la possibilité de reprise, nous avons créé une démo d’application de tâches qui s’exécute sur la périphérie Cloudflare. Cette page est prête pour l’interaction dans environ 50 ms.

Nous avons également utilisé la stratégie de reprise (et Qwik) pour refaire notre site Web, builder.io. En utilisant Qwik (et notre autre solution, Partytown), nous avons pu réduire de 99 % le JavaScript de notre site et obtenir un score PageSpeed ​​​​de 100/100. (Vous pouvez toujours visiter l’ancienne page en utilisant l’hydratation pour comparer et découvrir la différence de performance par vous-même.)

Conclusion

En termes simples, l’hydratation est une surcharge car elle duplique le travail. Le serveur construit le WHERE et WHAT (APP_STATE et FW_STATE), mais les informations sont ignorées au lieu d’être sérialisées pour le client. Le client reçoit alors du code HTML qui ne contient pas suffisamment d’informations pour reconstruire l’application. Le manque d’informations oblige le client à télécharger l’application avec impatience et à l’exécuter pour récupérer le OÙ et le QUOI.

Une approche alternative est la possibilité de reprise. La capacité de reprise se concentre sur le transfert de toutes les informations (OÙ et QUOI) du serveur au client. Seule une interaction de l’utilisateur force le client à télécharger du code pour gérer cette interaction spécifique. Le client ne duplique aucun travail du serveur ; par conséquent, il n’y a pas de frais généraux.

Image caractéristique via Pixabay.

Leave a Comment