
Partielle Hydratation für Next.js mit Preact X.
Erläuterung: Im Frühling erstellen wir Websites für Zeitungen und wir sind uns sehr, sehr leistungsrechtlich bewusst.
Zeitungen sind meistens statische Seiten. Wenn wir nun eine einzelne Seitenanwendung erstellen würden, würden wir ein riesiges Bündel mit meist unnötigem Code erstellen.
Dies bedeutet nicht nur, dass Benutzer darauf warten, dass eine große Datei heruntergeladen wird, sondern wie Addy Osmami darauf hinweist, dass bei der Parsen und Ausführung von Code enorme Leistungskosten auftreten. Als vage Faustregel können wir sagen, je größer Ihr Bündel ist, desto schlechter Ihre Leistung.
Aus diesem Grund wollen wir die Bündelgröße senken, indem wir den Code, den wir tatsächlich im Client benötigen, nur versenden und den Rest der Server -Seite -Rendering überlassen.
Dieses Repo ist immer noch ein Beweis für das Konzept, wir werden weiterhin daran arbeiten und unsere Arbeit als 2 Pakete implementieren:
pool-attendant-preact einer Bibliothek, die partialische Hydratation mit Preact x implementiertnext-super-performance A Next.js Plugin, das Pool-Antriebsantrieb verwendet, um die Kundenseite zu verbessern Zusätzlich zur partiellen Hydratation werden wir Ladestrategien wie critical CSS , critical JS , lazy loading , preloading ressources usw. im Rahmen der Nächsten-Super-Performance implementieren.
Im Moment haben wir eine partielle Hydratation POC für Next.js und so funktioniert es. Wenn Sie eine next.config.js erstellen und unser Plugin so verwenden
const withSuperPerformance = require ( "next-super-performance" ) ;
module . exports = withSuperPerformance ( ) ;2 Dinge werden passieren:
React wird durch Preact ersetzt, da es nur 3 KB ist Das bedeutet, dass Sie einen client.js im Stammordner Ihrer App erstellen müssen, der als Einstiegspunkt für das JavaScript fungiert, das an den Client gesendet wird. Wir tun dies, um Ihnen die volle Kontrolle darüber zu geben, was Ihre Benutzer herunterladen sollen, und um die für Sie geeignete Ladestrategie zu wählen.
Jetzt kommt pool-attendant-preact ins Spiel. POOL-ATTENDANT-Vorwirkungs-Exporte 3 APIs für Sie:
withHydration A hoc, mit dem Sie Ihre Komponenten für die Flüssigkeitszufuhr markieren könnenhydrate eine Funktion zur hydratmarkierten Komponenten im ClientHydrationData Eine Komponente, die serialisierte Requisiten an den Client schreibt, wie NEXT_DATA 
Lassen Sie uns dies mit gutem Beispiel erklären. Angenommen, Sie haben eine nächste App mit einem header , einem main und teaser (das beispielsweise nur Bilder mit einem Text und einer Überschrift sein kann). Für dieses Beispiel versuchen wir, die Teaser 2 und 3 dynamisch zu machen (nur um einige Elemente auf der Seite auszuwählen) und den Rest statisch zu lassen.
So würden Sie es tun:
Installieren Sie die Next-Super-Performance
npm i next-super-performance --save Erstellen Sie ein next.config.js und verwenden Sie das Plugin
const withSuperPerformance = require ( "next-super-performance" ) ;
module . exports = withSuperPerformance ( ) ; Ändern Sie Ihr package.json preact um die nächste Verwendung Preact react zu verwenden.
"scripts" : {
"dev" : "next:performance dev" ,
"start" : "next:performance start" ,
"build" : "next:performance build"
} , 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 >
) ;
} Der wichtige Teil hier ist <HydrationData /> , das so etwas einfügt:
< script type =" application/hydration-data " >
{ "1" : { "name" : "Teaser" , "props" : { "column" : 2 } } , "2" : { "name" : "Teaser" , "props" : { "column" : 3 } } }
</ script >Dies sind die Namen und Requisiten der Komponenten, die hydratisiert werden.
Um Ihrer App mitzuteilen, dass eine bestimmte Komponente withHydration werden sollte. Unsere main.js könnten so aussehen:
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 >
) ;
}In Zeile 4 haben wir eine Komponente erstellt, die im Client hydratisiert wird, und wir verwenden sie zweimal auf unserer Seite mit unterschiedlichen Requisiten.
withHydration werden Ihre Komponente mit einem Marker so vorbereitet, dass sie auf dem Server gerendert werden und in Ihrem HTML auf dem Client gefunden werden kann. Also wird <HydratedTeaser column={2} /> wird
< Fragment >
< script type = "application/hydration-marker" />
< Teaser column = { 2 } />
</ Fragment > Der letzte und wichtigste Teil sind Ihr client.js , der Code ist, der Ihren Benutzern versendet wird und wo Sie Ihre Komponenten feuchtigen. Für eine einzelne Komponente ( Teaser ) kann es einfach sein.
import { hydrate } from "next-super-performance" ;
import Teaser from "./components/teaser" ;
hydrate ( [ Teaser ] ) ; Oh, next-super-performance ist mit pool-attendant-preact geliefert. Deshalb importieren Sie alles von hier an und nicht von pool-attendant-preact . Es importiert und exportiert nur withHydration , hydrate und HydrationData zur Bequemlichkeit.
hydrate findet die Komponenten, die Sie unter Verwendung withHydration markiert haben, und verwenden die Daten von <HydrationData /> , um sie mit den Komponenten, die Sie als Array übergeben haben, mit den Komponenten zu hydratieren.
Auf diese Weise müssen Sie die Komponenten importieren, die Sie im Client verwenden möchten (und an die hydrate weitergeben). Da client.js der Einstiegspunkt für alle Ihren Client -Code ist, werden Sie auch genau angezeigt und steuern, welchen Code Sie an Ihre Benutzer senden. Abgesehen von der Vorwirkung wird nichts anderes versendet.
Wenn Ihre Komponenten Abhängigkeiten von selbst haben, werden diese Abhängigkeiten auch "natuaral" versendet, da client.js Ihr Eintrag ist und jede Abhängigkeit über WebPack gelöst wird.
Dieses Repo ist ein POC und etwas, auf das wir aufbauen werden. Um dies auszuprobieren, klonen Sie dieses Repository und laufen Sie dann aus
# 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 Dieser POC scheint recht gut zu funktionieren, wir könnten unsere Bündelgröße drastisch reduzieren. Es gibt jedoch noch viel zu tun. NEXT.js bündelt immer noch Code, den wir im Client nicht sehen möchten (wie core-js ). Außerdem möchten wir Tools und APIs implementieren, um eine Sprache für leistungskritische Aspekte Ihres Codes zu erstellen, um Ihnen Tools zur Definition Ihres kritischen Rendering-Pfades bereitzustellen.