
Hydratation partielle pour next.js avec préact X.
Explication: Au printemps, nous créons des sites Web pour les journaux et nous sommes très, très conscients des performances.
Les journaux sont principalement des pages statiques. Maintenant, si nous devions créer une seule application de page, nous créerions un immense pack avec un code pour la plupart inutile.
Cela ne signifie pas seulement que les utilisateurs attendent qu'un gros fichier télécharge, mais comme le souligne Addy Osmami, il y a un coût énorme de performances avec l'analyse et l'exécution du code. En règle générale, nous pouvons dire, plus votre paquet est grand, plus vos performances sont pires.
C'est pourquoi nous visons à couper la taille du faisceau en expédiant uniquement le code dont nous avons réellement besoin dans le client et en laissant le reste au rendu côté serveur.
Ce repo-ist est toujours une preuve de concept, nous continuerons à travailler sur cela et à mettre en œuvre notre travail en 2 packages:
pool-attendant-preact une bibliothèque qui met en œuvre une hydratation partielle avec Preact Xnext-super-performance un plugin Next.js qui utilise le pool-avantage-préact pour améliorer les performances côté client En plus de l'hydratation partielle, nous mettrons en œuvre des stratégies de chargement, notamment critical CSS , critical JS , lazy loading , preloading ressources , etc. dans le cadre de la performance suivante.
Pour l'instant, nous avons un POC d'hydratation partiel pour Next.js et c'est ainsi que cela fonctionne. Lorsque vous créez un next.config.js et utilisez notre plugin comme ainsi
const withSuperPerformance = require ( "next-super-performance" ) ;
module . exports = withSuperPerformance ( ) ;2 choses se produiront:
React sera remplacé par Preact car il n'est que de 3 Ko Cela signifie que vous devez créer un client.js dans le dossier racine de votre application qui agira comme le point d'entrée du JavaScript qui sera envoyé au client. Nous le faisons pour vous donner un contrôle total de ce que vous voulez que vos utilisateurs téléchargent et, très important, pour choisir la stratégie de chargement qui vous convient.
Maintenant, pool-attendant-preact entre en jeu. Pool-Atendant-Préact Exporte 3 API pour vous:
withHydration un hoc qui vous permet de marquer vos composants pour l'hydratationhydrate une fonction pour hydrater les composants marqués dans le clientHydrationData Un composant qui écrit des accessoires sérialisés au client, comme NEXT_DATA 
Expliquons ceci par l'exemple. Dites que vous avez une prochaine application avec un header , une section main et teaser S (qui peuvent être des images avec un texte et un titre, par exemple). Pour le bien de cet exemple, essayons de rendre les teasers 2 et 3 dynamique (juste pour choisir certains éléments sur la page) et laisser le reste statique.
Voici comment vous le feriez:
Installer la performance suivante
npm i next-super-performance --save Créez un next.config.js et utilisez le plugin
const withSuperPerformance = require ( "next-super-performance" ) ;
module . exports = withSuperPerformance ( ) ; Modifiez votre package.json pour effectuer le prochain utilisation correcte correctement (cela alimentera react à preact , puis démarrer les scripts suivants d'origine sans modification):
"scripts" : {
"dev" : "next:performance dev" ,
"start" : "next:performance start" ,
"build" : "next:performance build"
} , Créer pages/index.js
import Header from "../components/header" ;
import Main from "../components/main" ;
import { HydrationData } from "next-super-performance" ;
export default function Home ( ) {
return (
< section >
< Header />
< Main />
< HydrationData />
</ section >
) ;
} La partie importante ici est <HydrationData /> qui insérera quelque chose comme ceci:
< script type =" application/hydration-data " >
{ "1" : { "name" : "Teaser" , "props" : { "column" : 2 } } , "2" : { "name" : "Teaser" , "props" : { "column" : 3 } } }
</ script >Ce sont les noms et accessoires des composants qui seront hydratés.
Pour dire à votre application qu'un composant particulier doit être hydraté avec une utilisation withHydration . Nos main.js pourraient ressembler à ceci:
import Teaser from "./teaser" ;
import { withHydration } from "next-super-performance" ;
const HydratedTeaser = withHydration ( Teaser ) ;
export default function Body ( ) {
return (
< main >
< Teaser column = { 1 } />
< HydratedTeaser column = { 2 } />
< HydratedTeaser column = { 3 } />
< Teaser column = { 1 } />
< Teaser column = { 2 } />
< Teaser column = { 3 } />
< Teaser column = { 1 } />
< Teaser column = { 2 } />
< Teaser column = { 3 } />
</ main >
) ;
}Dans la ligne 4, nous avons créé un composant qui sera hydraté dans le client et nous l'utilisons 2 fois sur notre page avec différents accessoires.
withHydration a appliquer votre composant avec un marqueur afin qu'il puisse être rendu sur le serveur et être trouvé dans votre HTML sur le client. Donc <HydratedTeaser column={2} /> deviendra
< Fragment >
< script type = "application/hydration-marker" />
< Teaser column = { 2 } />
</ Fragment > La dernière partie et la plus cruciale est votre client.js qui est le code qui sera expédié à vos utilisateurs et où vous hydraterez vos composants. Pour un seul composant ( Teaser ), il peut être simple que cela.
import { hydrate } from "next-super-performance" ;
import Teaser from "./components/teaser" ;
hydrate ( [ Teaser ] ) ; Oh, next-super-performance est livrée avec pool-attendant-preact c'est pourquoi vous importez tout d'ici plutôt que de pool-attendant-preact . Il importe et exporte withHydration , hydrate et HydrationData pour plus de commodité.
hydrate trouvera les composants que vous avez marqués à l'aide withHydration et utilise les données de <HydrationData /> pour les hydrater avec les composants que vous leur avez transmis comme tableau.
Cela vous obligera à importer les composants que vous souhaitez utiliser chez le client (et à le transmettre à la fonction hydrate ). Étant donné que client.js est le point d'entrée pour tout votre code client, cela signifie également que vous verrez et contrôleras exactement le code que vous envoyez à vos utilisateurs. En dehors de Preact, rien d'autre ne sera expédié.
Si vos composants ont des dépendances par eux-mêmes, ces dépendances seront également expédiées "natuaralement" parce que client.js est votre entrée et que chaque dépendance sera résolue via WebPack.
Ce repo est un POC et quelque chose sur lequel nous allons construire. Pour essayer ceci, cloner ce référentiel puis courir
# Init Preact Git Sumodule
git submodule init
git submodule update
# Install dependencies
yarn
# Build Preact
cd packages/preact
yarn build
# Build the pool-attendant-preact package
# └─ cd to the pool-attendant-preact dir
cd ...
cd packages/pool-attendant-preact
# └─ build the package
yarn build
# cd to the app dir
cd ...
cd packages/app
# run the app
yarn dev Ce POC semble très bien fonctionner, nous pourrions considérablement réduire la taille de notre bundle. Il y a encore beaucoup à faire. Next.js regroupe toujours le code que nous ne voulons pas voir dans le client (comme core-js ). Nous visons également à implémenter des outils et des API pour créer un langage pour les aspects critiques de votre code pour vous fournir des outils pour définir votre chemin de rendu critique.