
Hidratación parcial para Next.js con Preact X.
Explicación: En Spring estamos creando sitios web para periódicos y somos muy, muy conscientes del rendimiento.
Los periódicos son en su mayoría páginas estáticas. Ahora, si creamos una aplicación de una sola página, crearíamos un gran paquete con un código en su mayoría innecesario.
Esto no solo significa que los usuarios esperan a que se descargue un archivo grande, sino que Addy Osmami señala hay un gran costo en el rendimiento con el análisis de análisis y ejecución. Como una regla general vaga, podemos decir, cuanto más grande sea su paquete, peor será su rendimiento.
Es por eso que nuestro objetivo es reducir el tamaño del paquete solo enviando el código que realmente necesitamos en el cliente y dejar el resto al lado del lado del servidor.
Este repositorio sigue siendo una prueba de concepto, continuaremos trabajando en esto e implementando nuestro trabajo como 2 paquetes:
pool-attendant-preact una biblioteca que implementa la hidratación parcialmente con PREACT Xnext-super-performance A Next.js complemento que utiliza el presente de actentización de piscinas para mejorar el rendimiento del lado del cliente Además de la hidratación parcial, implementaremos estrategias de carga que incluyen critical CSS , critical JS , lazy loading , preloading ressources , etc. como parte del rendimiento siguiente.
Por ahora tenemos un POC de hidratación parcial para Next.js y así es como funciona. Cuando crea un next.config.js y usa nuestro complemento como así
const withSuperPerformance = require ( "next-super-performance" ) ;
module . exports = withSuperPerformance ( ) ;2 cosas sucederán:
React será reemplazado por Preact porque solo es de 3 kb Eso significa que debe crear un client.js en la carpeta raíz de su aplicación que actuará como el punto de entrada para el JavaScript que se enviará al cliente. Hacemos esto para darle el control total de lo que desea que sus usuarios descarguen y, muy importante, para elegir la estrategia de carga adecuada para usted.
Ahora entra en juego pool-attendant-preact . API de exportaciones de Pool-Attendd-PRAACT 3 para usted:
withHydration un hoc que le permite marcar sus componentes para la hidrataciónhydrate una función para hidratar componentes marcados en el clienteHydrationData Un componente que escribe accesorios serializados para el cliente, como NEXT_DATA 
Expliquemos esto con el ejemplo. Digamos que tiene una siguiente aplicación con un header , una sección main y teaser S (que puede ser solo imágenes con un texto y un titular, por ejemplo). En aras de este ejemplo, intentemos hacer la dinámica de los teasers 2 y 3 (solo para elegir algunos elementos en la página) y dejar el resto estático.
Así es como lo harías:
Instalar el siguiente rendimiento
npm i next-super-performance --save Crea un next.config.js y usa el complemento
const withSuperPerformance = require ( "next-super-performance" ) ;
module . exports = withSuperPerformance ( ) ; Modifique su package.json para hacer que el próximo use Preact correctamente (esto react al alias para preact y luego comenzar los siguientes scripts originales sin modificación):
"scripts" : {
"dev" : "next:performance dev" ,
"start" : "next:performance start" ,
"build" : "next:performance build"
} , Crear 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 parte importante aquí es <HydrationData /> que insertará algo como esto:
< script type =" application/hydration-data " >
{ "1" : { "name" : "Teaser" , "props" : { "column" : 2 } } , "2" : { "name" : "Teaser" , "props" : { "column" : 3 } } }
</ script >Estos son los nombres y accesorios de los componentes que serán hidratados.
Para decirle a su aplicación que un componente particular debe ser hidratado con withHydration . Nuestro main.js podría verse así:
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 >
) ;
}En la línea 4 hemos creado un componente que se hidratará en el cliente y lo usamos 2 veces en nuestra página con diferentes accesorios.
withHydration prefirirá su componente con un marcador para que pueda representarse en el servidor y encontrar en su HTML en el cliente. Entonces <HydratedTeaser column={2} /> se convertirá
< Fragment >
< script type = "application/hydration-marker" />
< Teaser column = { 2 } />
</ Fragment > La última y más crucial parte es su client.js , que es el código que se enviará a sus usuarios y que es donde hidratará sus componentes. Para un solo componente ( Teaser ) puede ser simple como eso.
import { hydrate } from "next-super-performance" ;
import Teaser from "./components/teaser" ;
hydrate ( [ Teaser ] ) ; Oh, next-super-performance es con pool-attendant-preact por lo que importas todo desde aquí en lugar de desde pool-attendant-preact . Simplemente importe y exporta withHydration , hydrate e HydrationData para conveniencia.
hydrate encontrará los componentes que ha marcado usando withHydration y usará los datos de <HydrationData /> para hidratarlos con los componentes que les ha pasado como una matriz.
Esto requerirá que importe los componentes que desea usar en el cliente (y los pase a la función hydrate ). Debido a que client.js es el punto de entrada para todo el código de su cliente, esto también significa que verá y controlará exactamente qué código envía a sus usuarios. Aparte de preactuar, no se enviará nada más.
Si sus componentes tienen dependencias por su cuenta, esas dependencias serán enviadas "natuaralmente" porque client.js es su entrada y cada dependencia se resolverá a través de Webpack.
Este repositorio es un POC y algo en lo que construiremos. Para probar esto, clona este repositorio y luego ejecute
# 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 Este POC parece funcionar bastante bien, podríamos reducir drásticamente el tamaño de nuestro paquete. Sin embargo, todavía hay mucho que hacer. Next.js todavía agrupa el código que no queremos ver en el cliente (como core-js ). También nuestro objetivo es implementar herramientas y API para crear un lenguaje para aspectos críticos de rendimiento de su código para proporcionarle herramientas para definir su ruta de renderización crítica.