in Informatica, Typescript

React – Lazy Loading Routes

Reading Time: 2 minutes

All’interno di un applicazione React abbiamo la necessità di gestire le rotte per la visualizzazione dei diversi components presenti nell’applicazione.

In particolar modo è necessario un pacchetto specifico chiamato React Router.

React Router viene installato utilizzando il comando:

$> npm install react-router-dom

nel caso in cui venga installata la versione 5 è necessario sostituirla con la versione 6 utilizzando il comando:

$> npm install react-router-dom@next

Inoltre, poichè react-router utilizza history è necessario installare anche questo pacchetto:

$> npm install history

A questo punto è possibile gestire le rotte all’interno dell’applicazione, ad esempio importanto all’interno di App.tsx nel seguente modo:

import { BrowserRouter, Routers, Router } from 'react-router-dom';

...
...

<BrowserRouter>
  ...
  <Routes>
    <Route path="search" element={<SearchPage/>} />
  </Routes>
  ...
</BrowserRouter>

nell’esempio abbiamo dichiarato una rotta che esegue il match nella URL di search visualizzando il componenente chiamato SearchPage.

All’interno di BrowserRouter possiamo definire quante regole di routing vogliamo: la regola con il migliore matching sarà quella che consentirà di visualizzare il componente relativo.

Ovviamente è possibile definire tutte le regole di cui effettivamente abbiamo bisogno, e definire regole generiche ad esempio per fare il redirect per la richieste “not found”:

<Routes>
  <Router path "" element={<HomePage/>} />
  ...
  ...
  <Router path "search" element={<SearchPage/>} />
  <Router path "customers" element={<CustomerPage/>} />
  <Router path "*" element={<NotFound/>} />
</Routes>

Nell’esempio oltre alle rotte con il matching, sono gestite anche la regola generica per la home page (prima regola) e la regola per intercettare le rotte non definite (ultima regola).

Durante il caricamento dell’applicazione tutto il Javascript incluso viene caricato in fase di avvio.

La dimensione del javascript scaricato può impattare anche notevolmente sulle performance. Si può optare per caricare i component/pagine di grandi dimensioni, solo quando ne abbiamo effettivamente la necessità. Questo meccanismo prende il nome di lazy loading.

Supponiamo di avere il seguente componente AskPage.tsx:

export const AskPage = () => <Page title="Ask"/>;
export default AskPage;

e di renderizzarlo a partire da App.tsx. Modifichiamo il file App.tsx rimuovendo l’import di AskPage e sostituendolo con :

import React from 'react';
const AskPage = React.lazy(()=>import('./AskPage'));

in pratica tramite il caricamento lazy stiamo utilizzando l’import dinamico per un componente . Il caricamento lazy restituisce una Promise per il caricamento di un componente. In questo modo AskPage sarà caricato solo quanto ne avremo effettivamente la necessità.

Al momento App.tsx si aspetta di caricare AskPage in maniera tradizionale, e se proviamo ad accedere alla sua route, riceveremo un messaggio di errore. La soluzione è quella di modificare la route nel seguente modo:

<Route path='ask' element={ <React.Suspense fallback={<div>Loading...</div>}><AskPage/></React.Suspense>} />

L’utilizzo di Suspense fallback consente di effetturare il render di un componente durante il caricamento di AskPage. In questo caso verrà visualizzato “Loading…”