Verwende React.lazy mit Vertrauen: Eine sichere Möglichkeit, Komponenten bei schnellem Iterieren zu laden
React.lazy ist eine großartige Möglichkeit, Komponenten bei Bedarf zu laden und die Leistung deiner App zu verbessern. Es kann jedoch zu einigen Problemen wie "ChunkLoadError" und "Loading chunk failed" führen.
Das Dilemma
Heutzutage entwickelt sich die Softwareentwicklung immer schneller unter der populären Philosophie des "move fast and break things". Keine Wertung hier - es ist einfach so, wie die Dinge sind. Dieses schnelle Tempo kann jedoch manchmal zu Problemen führen, insbesondere wenn es darum geht, Komponenten in React zu laden.
Wenn du an einem Projekt arbeitest, das React.lazy verwendet, um Komponenten bei Bedarf zu laden, bist du möglicherweise auf Probleme wie ChunkLoadError
und Loading chunk failed
gestoßen. Hier sind einige mögliche Gründe:
- Es gibt ein Netzwerkproblem, zum Beispiel eine langsame oder instabile Internetverbindung des Nutzers.
- Der Nutzer verwendet eine veraltete Version der App, und der Browser versucht, einen Chunk zu laden, der nicht mehr existiert.
In der Regel kann ein einfaches Neuladen der Seite das Problem lösen, aber es ist keine großartige Erfahrung für den Nutzer. Stell dir vor, ein weißer Bildschirm erscheint, während der Nutzer zu einer anderen Route navigiert - das ist kein guter Eindruck für deine App.
Können wir das Bedürfnis nach Geschwindigkeit mit einer reibungslosen Benutzererfahrung in Einklang bringen? Sicher. Lass mich dir zeigen, wie (natürlich mit TypeScript).
Die Lösung
Eine brutale Lösung könnte darin bestehen, alle Versionen der Chunks auf dem Server zu speichern, wodurch das Problem des "fehlenden Chunks" nicht mehr besteht. Wenn deine App wächst, kann diese Lösung jedoch unpraktikabel werden, da der Bedarf an Speicherplatz zunimmt, und sie löst das Netzwerkproblem immer noch nicht.
Da ein erneuter Versuch oder ein Neuladen das Problem lösen kann, können wir diese Lösungen in unseren Code implementieren. Da das Problem normalerweise auftritt, wenn der Nutzer zu einer anderen Route navigiert, können wir es lösen, ohne dass der Nutzer es bemerkt. Alles, was wir tun müssen, ist eine Wrapper-Funktion um die React.lazy
-Funktion zu bauen, die die erneuten Versuche und das Neuladen behandelt.
Es gibt bereits einige großartige Artikel darüber, wie eine solche Lösung implementiert wird, daher werde ich mich auf die Idee und das Innenleben der Lösung konzentrieren.
Erstelle den Wrapper
Der erste Schritt besteht darin, eine Wrapper-Funktion um die React.lazy
-Funktion zu erstellen:
Behandle die Versuche
Für Netzwerkprobleme können wir die Versuche behandeln, indem wir die importFunction
in eine tryImport
-Funktion einwickeln:
Sieht einfach aus, oder? Du kannst auch den Algorithmus des exponentiellen Backoff implementieren, um die Versuche effizienter zu behandeln.
Behandle das Neuladen
Bei einem Problem mit der veralteten Version können wir das Neuladen behandeln, indem wir den Fehler abfangen und die Seite aktualisieren:
Diese Implementierung ist jedoch sehr gefährlich, da sie zu einer Endlosschleife von Neuladen führen kann, wenn der Fehler nicht durch ein Neuladen behoben wird. Gleichzeitig geht der Zustand der App während des Neuladens verloren. Daher benötigen wir die Hilfe von sessionStorage
, um die Nachricht zu speichern, die besagt, dass wir die Seite versucht haben, zu aktualisieren:
Nun wissen wir, wenn wir den Fehler aus der safeLazy
-Funktion abfangen, dass es sich um etwas handelt, das nicht durch ein Neuladen behoben werden kann.
Mehrere Lazy-Komponenten auf derselben Seite
Es gibt immer noch eine versteckte Falle mit der aktuellen Implementierung. Wenn du mehrere Lazy-Komponenten auf derselben Seite hast, kann die Endlosschleife von Neuladen weiterhin auftreten, da andere Komponenten möglicherweise den sessionStorage
-Wert zurücksetzen. Um dieses Problem zu lösen, können wir für jede Komponente einen eindeutigen Schlüssel verwenden:
Nun hat jede Komponente ihren eigenen sessionStorage
-Schlüssel, und die Endlosschleife von Neuladen wird vermieden. Wir könnten die Lösung weiter verfeinern, zum Beispiel:
- Sammle alle Schlüssel in einem Array, so dass nur ein Speicherplatzschlüssel benötigt wird.
- Setze ein Limit für das Neuladen, damit die Seite mehr als einmal aktualisiert wird, bevor ein Fehler geworfen wird.
Aber ich denke, du hast die Idee verstanden. Eine umfassende TypeScript-Lösung mit Tests und Konfigurationen ist im GitHub-Repository verfügbar. Außerdem habe ich das react-safe-lazy
-Paket auf NPM veröffentlicht, so dass du es sofort in deinem Projekt verwenden kannst.
Fazit
Softwareentwicklung ist eine empfindliche Arbeit, und selbst die kleinsten Details können Mühe kosten, sie zu lösen. Ich hoffe, dieser Artikel kann dir helfen, die Probleme mit React.lazy
elegant zu bewältigen und die Benutzerfreundlichkeit deiner App zu verbessern.