Reprise contre hydratation – une bataille injuste ?
La technique de rendu côté serveur est devenue plus accessible. Nous avons vu comment de nombreux méta-frameworks ont investi beaucoup de ressources pour les rendre simples à activer. Longs sont les jours où il fallait beaucoup investir et comprendre les choses.
Nous voyons à quel point le méta-framework ressemble à NextJs
, Remix
, Nuxtjs
et plus l’incluent par défaut. Cadres React
ont conçu de nouvelles API où vous pouvez même avoir des composants exécutés uniquement sur le serveur. Ce sont maintenant la valeur par défaut sur NextJs
.
L’hydratation a été la technique reine lors de l’ajout d’interactivité à une page HTML SSR. Il a été affiné au fil des ans pour devenir plus efficace et différentes stratégies sont disponibles. Récemment, nous avons vu apparaître un nouveau concept : la possibilité de reprise.
Où en est-il ? Peut-il battre l’hydratation? Comment pouvons-nous commencer à jouer avec ?
La technique d’hydratation SSR n’est pas une solution miracle. Bien qu’il ait stimulé la First Contentful Paint
et Largest Contentful Paint
métriques en expédiant un HTML rendu par le serveur, il doit encore télécharger, analyser et exécuter une tonne de JavaScript.
Cela a un impact sur la Time To Interactive
métrique. Cela devient frustrant lorsque la page ne répond pas aux clics. Comment l’hydratation peut-elle le combattre ? Il existe une grande variété de :
1. Hydratation sélective
C’était l’un des problèmes que React 18
a abordé avec la fonction d’hydratation sélective. Au lieu de simplement jeter les résultats de renderToString
méthode, le HTML peut maintenant être diffusé en continu. Comment? En utilisant la nouvelle API suivante :
// opting to streaming HTML
import { pipeToNodeWritable } from ‘react’;
Les composants peuvent être lazy-loaded
à la fin du serveur et expédier un minimum de JavaScript en utilisant leur Suspense
caractéristique.
De plus, lorsqu’un utilisateur interagit avec un composant non hydraté, il sera prioritaire. Tout cela est possible grâce au mode concurrent.
2. Hydratation partielle
C’est un concept où tous les composants ne sont pas toujours hydratés. Certains composants peuvent ne présenter aucun avantage en matière d’hydratation, alors pourquoi le faire ? Cela rejoint l’idée de Island Architecture
par Jason Miller. Il est largement mis en œuvre par le Astro
méta-framework.
Le React Server Components
sont les React
l’équipe s’occupe de cette affaire. Ces composants expédieraient n’importe quel code JavaScript ou même seraient hydratés à moins qu’un Client Component
y est rendu. Seulement dans ce scénario, certains JavaScript seront expédiés. Des cadres comme NextJs
ou alors Gatsby
investissent massivement dans cette fonctionnalité.
3. Hydratation progressive
Lors de la création d’applications Web, nous pouvons toujours faire la distinction entre les composants critiques et les moins importants. Nous pouvons conditionnellement rendre ceux que nous trouvons pour apporter plus de valeur. Ce concept a été présenté lors de Google I/O 2019.
Par exemple, nous pouvons retarder l’exécution des composants qui se trouvent en dehors de la fenêtre. Tout comme le lazy-loading
technique de navigateur prise en charge nativement.
Le processus d’hydratation a été affiné au fil des ans avec les techniques vues ci-dessus. Cependant, son inconvénient est toujours le même : une tonne de JavaScript est nécessaire juste pour restituer l’arbre qui a déjà été construit sur le serveur. Comment se débarrasser de ce goulot d’étranglement redondant ?
Le Resumable
concept semble être la solution parfaite. Cela réduit le besoin d’hydratation et donc le navigateur n’a pas besoin de télécharger une tonne de JavaScript. Comment cela est-il possible? Le HTML SSR résultant contient une sérialisation des informations nécessaires pour reprendre instantanément son exécution sur le navigateur. Assez doux n’est-ce pas?
Voyons un diagramme ci-dessous montrant le peu de travail qui doit être fait par le navigateur.
Le principal acteur sur le Resumable
le concept est Qwik
. Comment peut-il sérialiser toute l’exécution côté serveur de l’application ? En résolvant quatre problèmes principaux :
- Les auditeurs: il sérialise et produit des écouteurs d’événements à chargement différé dans le DOM. Chaque gestionnaire est sérialisé dans son propre bloc. Le
Qwikloader
configure un écouteur d’événement global pour télécharger chaque morceau à la demande.
Il prend en charge les fermetures de fonctions, les références DOM, les promesses, la carte, l’ensemble et la sérialisation des objets URL. Il y a quelques limitations que le développeur doit garder à l’esprit, comme la sérialisation des flux.
<button on:click="./chunk.js#handler_symbol">click me</button>
- Arborescence des composants : au moment du SSR/SSG, Qwik collecte et sérialise les informations sur la relation entre les composants et les magasins, et les abonnements. Cela lui permettra de mettre à jour/re-rendre le composant pertinent en cas de besoin. Comme toutes les limites des composants sont maintenant transmises, il ne nécessite aucun processus d’hydratation. Comment cela est-il réalisé ? Principalement via HTML
<!-- comments -->
- État de l’application : Qwik fournit une implémentation de gestion d’état. L’état de l’application sera sérialisé avec la réponse HTML en tant que
<script />
de typeqwik/json
. - Code spécifique au client : puisqu’il n’y a pas d’hydratation, quand le code spécifique au client s’exécute-t-il ? Il y a un
useClientEffect$
abstraction. Cela exécutera le rappel JavaScript lorsque le composant deviendra visible.
En un mot, la principale force de Qwik
est qu’il est capable de sérialiser l’exécution sur le serveur afin qu’elle puisse être reprise sur le client. Ensuite, il est capable de rendre progressivement l’application interactive en ne téléchargeant que le JavaScript pertinent. Initialement, sur le client, nous avons juste besoin du code du QwikLoader
qui est aligné et pèse autour 1kb
.
Cela maintiendra l’exécution initiale de l’application rapide comme l’éclair, quelle que soit la complexité de l’application. C’est pourquoi on l’appelle le premier O(1)
cadre de temps de chargement de la page.
Expédier moins de code JavaScript n’est pas seulement meilleur parce que nous utilisons moins de bande passante. Cela signifie également que nous avons besoin de moins de clients gourmands en énergie car il y aura beaucoup moins de code analysé et exécuté. Nous ne gaspillerons pas non plus de cycles CPU sur du code qui sera probablement nécessaire au client. Le chargement paresseux à grain fin signifie que nous n’exécuterons que le code JavaScript nécessaire au client.
Cela signifie également que l’application deviendra progressivement interactive. Au fur et à mesure que l’utilisateur interagit avec l’application, plus de code sera téléchargé.
La mise en œuvre de la Qwik
est fascinante et va changer la façon dont nous écrivons des applications Web. Cependant, cela ne vient pas gratuitement. Nous devrons passer à un plus DOM
approche centrée. Nous serons également confinés à un fournisseur et nous devrons utiliser son approche d’état et de routage.
La vitesse s’est avérée être un élément clé lors de la conception d’un site. Le temps, c’est de l’argent. Il existe des mesures montrant comment la page se charge avec aussi peu de 100ms
les deltas ont un impact sur la conversion des clients.
Envoyer moins de code JavaScript semble être la technique la plus efficace de toutes. Les dernières techniques d’hydratation ont eu cet objectif en tête. Nous avons également constaté cette tendance à la réduction de JavaScript sur certains des méta-frameworks les plus populaires.
La stratégie de reprise semble avoir atterri pour rester. En voyant comment il mûrit, nous verrons sûrement comment l’adoption monte en flèche. Ce n’est que le début. Il y a plus d’optimisations qui peuvent être combinées avec cela comme pré-chargement pour les réseaux lents.
Actuellement, Qwik a à peine atteint le jalon bêta. Cependant, comme seuls quelques changements de rupture sont attendus, il vaut la peine de l’envisager pour une utilisation en production.