Använd React.lazy med tillförsikt: Ett säkert sätt att ladda komponenter när du itererar snabbt
React.lazy är ett fantastiskt sätt att ladda komponenter vid behov och förbättra prestandan för din app. Men ibland kan det orsaka problem som "ChunkLoadError" och "Loading chunk failed".
Dilemmat
Nu för tiden rör sig mjukvaruutveckling snabbare under den populära "move fast and break things"-filosofin. Ingen bedömning här - det är bara så det är. Men denna snabba takt kan ibland leda till problem, särskilt när det gäller att ladda komponenter i React.
Om du arbetar på ett projekt som använder React.lazy för att ladda komponenter vid behov, kanske du har stött på några problem som ChunkLoadError
och Loading chunk failed
. Här är några möjliga orsaker:
- Det finns ett nätverksproblem, till exempel att användarens internetanslutning är långsam eller instabil.
- Användaren är på en föråldrad version av appen och webbläsaren försöker ladda en chunk som inte längre finns.
Vanligtvis kan en enkel siduppdatering lösa problemet, men det är inte en bra upplevelse för användaren. Tänk om en vit skärm visas när användaren navigerar till en annan ruta - det är inte bra för din app.
Kan vi balansera behovet av fart med behovet av en smidig användarupplevelse? Självklart. Låt mig visa dig hur (med TypeScript, förstås).
Lösningen
En våldsam lösning kan vara att spara alla versioner av chunkar på servern, vilket alltså eliminerar problemet med "saknad chunk". När din app växer kan denna lösning bli opraktisk på grund av ökade diskutrymmeskrav, och det löser fortfarande inte nätverksproblemet.
Med tanke på att en omstart eller uppdatering kan lösa problemet, kan vi implementera dessa lösningar i vår kod. Eftersom problemet vanligtvis uppstår när användaren navigerar till en annan ruta, kan vi lösa det utan att användaren märker det. Allt vi behöver göra är att bygga en omslag runt React.lazy
-funktionen som hanterar omstarter och uppdateringar.
Det finns redan några bra artiklar om hur man implementerar denna typ av lösning, så jag kommer att fokusera på idén och de inre funktionerna av lösningen.
Skapa omslaget
Första steget är att skapa ett omslag runt React.lazy
-funktionen:
Hantera omstarter
För nätverksproblem kan vi hantera omstarter genom att lägga importFunction
i en tryImport
-funktion:
Ser enkelt ut, eller hur? Du kan också implementera exponential backoff-algoritmen för att hantera omstarter mer effektivt.
Hantera uppdateringar
För problemet med föråldrade versioner kan vi hantera uppdateringar genom att fånga felet och uppdatera sidan:
Men denna implementering är mycket farlig, eftersom den kan orsaka en oändlig loop av uppdateringar när felet inte kan lösas genom en uppdatering. Samtidigt kommer apptillståndet att gå förlorat under uppdateringen. Så vi behöver hjälp av sessionStorage
för att lagra meddelandet att vi har försökt att uppdatera sidan:
Nu, när vi fångar felet från safeLazy
-funktionen, vet vi att det är något som inte kan lösas genom en uppdatering.
Flera lazy-komponenter på samma sida
Det finns fortfarande en dold fallgrop med den nuvarande implementeringen. Om du har flera lazy-komponenter på samma sida, kan den oändliga loopen av uppdateringar fortfarande hända eftersom andra komponenter kan återställa sessionStorage
-värdet. För att lösa detta problem kan vi använda en unik nyckel för varje komponent:
Nu kommer varje komponent att ha sin egen sessionStorage
-nyckel, och den oändliga loopen av uppdateringar kommer att undvikas. Vi kan fortsätta att kritiskt granska lösningen, till exempel:
- Samla alla nycklar i en array, så att endast en lagringsnyckel behövs.
- Ställ in en uppdateringsgräns för att uppdatera sidan mer än en gång innan ett fel kastas.
Men jag tror att du förstår idén. En omfattande TypeScript-lösning med tester och konfigurationer finns tillgänglig i GitHub-repoet. Jag har också publicerat react-safe-lazy
-paketet på NPM, så du kan använda den i ditt projekt direkt.
Slutsats
Mjukvaruutveckling är ett noggrant arbete, och även de minsta detaljerna kan kräva ansträngning att lösa. Jag hoppas denna artikel kan hjälpa dig att hantera problemen med React.lazy
smidigt och förbättra din apps användarupplevelse.