Es ist 2019! Jeder glaubt, die Code-Aufteilung zu kennen. Also - lasst uns noch einmal nachsehen!

Wofür steht Code-Splitting?
Kurz gesagt, beim Teilen von Kurzcode geht es nur darum, nicht eine ganze Sache zu laden. Wenn Sie diese Seite lesen, müssen Sie nicht eine ganze Site laden. Wenn Sie eine einzelne Zeile aus einer Datenbank auswählen, müssen Sie nicht alle übernehmen.
Offensichtlich? Die Aufteilung des Codes ist ebenfalls ziemlich offensichtlich, nur nicht über Ihre Daten, sondern über Ihren Code.
Wer (was?) Macht das Aufteilen von Code?
React.lazy
? Nein - es benutzt es nur. Die Code-Aufteilung erfolgt auf Bundler-Ebene - Webpack, Paket oder nur Ihr Dateisystem für den Fall, dass es sich um "native" ESM-Module handelt. Code-Splitting besteht nur aus Dateien, Dateien, die Sie "später" irgendwo laden können. Also - auf die Fragen " Was macht das Aufteilen von Code aus? " - lautet die Antwort - ein "Bündler".
Wer (was) verwendet die Codeaufteilung?
React.lazy
verwendet. Verwenden Sie einfach die Codeaufteilung Ihres Bundlers. Rufe einfach den Import auf, wenn er gerendert wurde. Und das ist alles.
Was ist mit React-loadable?
React.lazy
hat es abgelöst. Und bietet weitere Funktionen wie Suspense
zur Steuerung des Ladezustands. Verwenden React.Lazy
stattdessen React.Lazy
.
Ja, das ist alles. Vielen Dank fürs Lesen und einen schönen Tag.
Warum ist der Artikel nicht fertig?
Nun. Es gibt ein paar Grauzonen über React.lazy
und Code-Splitting, die ich vergessen habe zu erwähnen.
Grauzone 1 - Testen
Aufgrund seiner Asynchronität ist es nicht einfach, React.lazy
zu testen. Es wäre nur "leer", solange es noch nicht geladen ist (auch wenn es so ist) - Promises
und import
, und faul akzeptiert Versprechen , die immer im nächsten Tick ausgeführt wurden .
Vorgeschlagene Lösung? Sie würden es nicht glauben, aber die vorgeschlagene Lösung besteht darin, synchrone Thenables zu verwenden - siehe Pull-Anfrage . Also - machen wir unsere imports
SYNCHRON !!! (um ein faules Problem für die Tests oder einen anderen serverseitigen Fall zu beheben)
const LazyText = lazy(() => ({ then(cb) { cb({default: Text});
Es ist nicht schwer, die Importfunktion in eine gespeicherte synchrone Funktion umzuwandeln.
const syncImport = (importFn) => { let preloaded = undefined; const promise = importFn().then(module => preloaded = module);
Grauzone 2 - SSR
Wenn Sie keine SSR benötigen, lesen Sie bitte den Artikel weiter!
React.lazy
ist SSR-freundlich. Aber Suspense
funktionieren, und Suspense ist NICHT serverseitig .
Es gibt 2 Lösungen:
Dies ist eine gute Option, aber nicht sehr kundenfreundlich. Warum? Definieren wir die 2. mögliche Lösung:
- Verwenden Sie eine spezielle Bibliothek , um verwendete Skripte, Chunks und Stile zu verfolgen und auf der Clientseite zu laden (insbesondere Stile!), Bevor Sie auf die Hydratation reagieren. Oder Sie würden leere Löcher anstelle Ihrer Code-geteilten Komponenten rendern. Noch einmal - Sie haben den Code, den Sie gerade geteilt haben, nicht geladen, sodass Sie nichts rendern können, was Sie wollen.
Siehe Code-Splitting-Bibliotheken
- Universalkomponente - die älteste und noch zu wartende Bibliothek. Es "erfand" die Code-Aufteilung im Sinne von Webpack, um die Code-Aufteilung zu lehren.
- React-loadable - sehr beliebt, aber eine nicht gepflegte Bibliothek. Code spucken zu einer beliebten Sache gemacht. Die Probleme sind geschlossen, daher gibt es keine Community.
- Loadable-Components - eine funktionsreiche Bibliothek, deren Verwendung mit der aktivsten Community der Umgebung eine Freude ist.
- Importierte Komponente - eine einzelne Bibliothek, die nicht an Webpack gebunden ist, d. H. Paket oder ESM verarbeiten kann.
- React-Async-Komponente - bereits tote Bibliothek (noch immer beliebt), die einen erheblichen Einfluss auf alles rund um die Code-Aufteilung, die benutzerdefinierte React-Tree-Traversal und SSR hatte.
- Eine andere Bibliothek - es gab viele Bibliotheken, von denen viele die Webpack-Evolution oder React 16 nicht überlebten - ich habe sie hier nicht aufgelistet, aber wenn Sie einen guten Kandidaten kennen - DM mich einfach.
Welche Bibliothek soll ich auswählen?
Es ist einfach - nicht reaktionsladbar - es ist schwer, nicht gewartet und veraltet, auch wenn es immer noch sehr beliebt ist. (und nochmals vielen Dank, dass Sie die Code-Aufteilung populär gemacht haben)
Ladbare Komponenten - könnten eine sehr gute Wahl sein. Es ist sehr gut geschrieben, wird aktiv gepflegt und unterstützt alles sofort. Unterstützt "volldynamische Importe", so dass Sie Dateien abhängig von den angegebenen Requisiten importieren können, aber somit nicht typisierbar sind. Unterstützt Spannung, könnte also React.lazy ersetzen.
Universal-Komponente - eigentlich "Erfinder" der volldynamischen Importe - haben sie in Webpack implementiert. Und viele andere Dinge auf niedrigem Niveau - sie haben es getan. Ich würde sagen - diese Bibliothek ist ein bisschen hardcore und ein bisschen weniger benutzerfreundlich. Die Dokumentation zu ladbaren Komponenten ist unschlagbar. Es lohnt sich, diese Bibliothek nicht zu verwenden und dann die Dokumentation zu lesen - es gibt so viele Details, die Sie kennen sollten ...
Reagieren-importierte-Komponente - ist ein bisschen seltsam. Es ist bündlerunabhängig, würde also niemals kaputt gehen (es gibt nichts zu kaputt), würde mit Webpack 5 und 55 funktionieren, aber das ist mit Kosten verbunden. Während frühere Bibliotheken während der SSR alle verwendeten Skripte zum Seitenkörper hinzufügten, können Sie alle Skripte parallel laden - importierte kennen keine Dateinamen und rufen die ursprünglichen "Importe" auf (aus diesem Grund Bundle) unabhängig), um gebrauchte Chunks zu laden, aber nur innerhalb des Hauptpakets aufrufen zu können - daher werden alle zusätzlichen Skripte erst geladen, nachdem das Haupt-Skripte heruntergeladen und ausgeführt wurde. Unterstützt keine vollständigen dynamischen Importe wie React.lazy und ist daher typisierbar. Unterstützt auch Suspense. Verwendet synchrone Thenables auf SSR. Es hat auch einen völlig anderen Ansatz für CSS und eine perfekte Unterstützung für das Rendern von Streams.
Es gibt keinen Unterschied in Qualität oder Beliebtheit zwischen den aufgelisteten Bibliotheken, und wir sind alle gute Freunde - wählen Sie also auswendig.
Grauzone 3 - Hybridrender
SSR ist eine gute Sache, aber schwer. Kleine Projekte möchten möglicherweise eine SSR - es gibt viele Gründe dafür -, möchten sie jedoch möglicherweise nicht einrichten und warten.
SSR könnte wirklich WIRKLICH schwer sein. Versuchen Sie es mit Razzle oder gehen Sie mit Next.js, wenn Sie schnell gewinnen möchten.
Die einfachste Lösung für SSR, insbesondere für einfaches SPA, wäre das Vorrendern. Öffnen Sie Ihr SPA in einem Browser und klicken Sie auf "Speichern". Wie:
- React-Snap - verwendet Puppenspieler (auch bekannt als kopfloses Chrome), um Ihre Seite in einem "Browser" zu rendern und ein Ergebnis als statische HTML-Seite zu speichern.
- Rendertron - das macht das Gleiche, aber auf eine andere ( Cloud- ) Weise.
Das Vorrendern ist "SSR" ohne "Server". Es ist SSR mit einem Client. Magie! Und sofort einsatzbereit ... ... ... aber nicht zum Code-Spucken.
Also - Sie haben Ihre Seite gerade in einem Browser gerendert, HTML gespeichert und aufgefordert, dasselbe Material zu laden. Es wurde jedoch kein serverseitiger spezifischer Code (zum Sammeln aller verwendeten Chunks) verwendet, da es keinen Server gibt !

Im vorherigen Teil habe ich auf Bibliotheken hingewiesen, die an Webpack gebunden sind, um Informationen über verwendete Chunks zu sammeln - sie konnten überhaupt nicht mit Hybrid-Rendering umgehen.
Loadable-Components Version 2 (nicht kompatibel mit der aktuellen Version 5) wurde teilweise von React-Snap unterstützt. Die Unterstützung ist weg.
Eine reaktionsimportierte Komponente könnte diesen Fall behandeln, solange sie nicht an den Bündler / die Seite gebunden ist. Daher gibt es keinen Unterschied für SSR oder Hybrid, sondern nur für React-Snap, solange sie die "Zustandshydratation" unterstützt. während Rendertron dies nicht tut.
Diese Fähigkeit der reaktionsimportierten Komponente wurde beim Schreiben dieses Artikels festgestellt, sie war vorher nicht bekannt - siehe Beispiel . Es ist ganz einfach.
Und hier müssen Sie eine andere Lösung verwenden, die gerade senkrecht zu allen anderen Bibliotheken ist.
Vorgerenderte Komponente reagieren
Diese Bibliothek wurde für die teilweise Hydratation erstellt und kann Ihre App teilweise rehydrieren, sodass der Rest immer noch nicht hydratisiert ist. Und es funktioniert für SSR- und Hybrid-Renderer ohne Unterschied.
Die Idee ist einfach:
- während der SSR - Rendern Sie die Komponente mit einem <div />
- auf dem Client - finden Sie dieses div und verwenden Sie innerHTML, bis Component bereit ist, totes HTML zu ersetzen.
- Sie müssen nicht laden und warten, bis ein Block mit geteilter Komponente vorhanden ist, bevor Sie
hydrate
, um stattdessen KEIN weißes Loch zu rendern. Verwenden Sie einfach vorgerendertes HTML, das absolut dem entspricht, das eine echte Komponente rendern würde, und welches existiert bereits - es kommt mit einer Server- (oder Hydrid-) Antwort.
Aus diesem Grund müssen wir warten, bis alle Chunks geladen sind, bevor wir hydratisieren - um dem vom Server gerenderten HTML-Code zu entsprechen. Aus diesem Grund könnten wir Teile von vom Server gerendertem HTML verwenden, bis der Client nicht bereit ist - es entspricht dem, den wir nur produzieren werden.
import {PrerenderedComponent} from 'react-prerendered-component'; const importer = memoizeOne(() => import('./Component'));
Es gibt einen weiteren Artikel über diese Technologie , den Sie vielleicht lesen. Aber hauptsächlich hier - es löst "Flash Of Unloaded Content" in einem anderen, nicht für Code-Splitting-Bibliotheken üblichen Weg. Seien Sie offen für neue Lösungen.
TLDR?
- Verwenden Sie nicht reaktionsladbar, es würde keinen wertvollen Wert hinzufügen
- React.lazy ist gut, aber noch zu einfach.
- SSR ist eine schwierige Sache, und Sie sollten es wissen
- Hybrid Puppenspieler-gesteuertes Rendering ist eine Sache. Manchmal noch schwieriger.