Suddivisione del codice con importazioni dinamiche in Next.js

Come velocizzare la tua app Next.js con la suddivisione del codice e strategie di caricamento intelligente.

Milica Mihajlija
Milica Mihajlija

Cosa imparerai?

Questo post illustra i diversi tipi di codice suddivisione dei dati e come utilizzare importazioni dinamiche per velocizzare le tue app Next.js.

Suddivisione del codice basata su route e componenti

Per impostazione predefinita, Next.js suddivide il codice JavaScript in blocchi separati per ogni route. Quando gli utenti caricano la tua applicazione, Next.js invia solo il codice necessario per percorso iniziale. Quando gli utenti esplorano l'applicazione, recuperano i blocchi associate alle altre route. La suddivisione del codice basata su route riduce al minimo di script che devono essere analizzati e compilati contemporaneamente, ottenendo tempi di caricamento delle pagine più rapidi.

Sebbene la suddivisione del codice basata su route sia un'impostazione predefinita, puoi ottimizzare ulteriormente processo di caricamento con suddivisione del codice a livello di componente. Se hai grandi dimensioni componenti della tua app, è un'ottima idea suddividerli in blocchi separati. In questo modo, tutti i componenti di grandi dimensioni che non sono critici o vengono visualizzati solo Le interazioni degli utenti (come i clic su un pulsante) possono essere eseguite con il caricamento lento.

Next.js supporta le creatività dinamiche import(), che ti consente di importare moduli JavaScript (inclusi i componenti React) in modo dinamico e caricare ogni importazione come un blocco separato. In questo modo la suddivisione del codice a livello di componente e consente di controllare il caricamento gli utenti scarichino il codice di cui hanno bisogno solo per la parte del sito che che sta visualizzando. In Next.js, questi componenti vengono sottoposti a rendering lato server (SSR) per impostazione predefinita.

Importazioni dinamiche in azione

Questo post include diverse versioni di un'app di esempio che consiste in una semplice pagina con un pulsante. Quando fai clic sul pulsante, puoi vedere un simpatico cucciolo. Come passi da una versione all'altra dell'app, vedrai come le importazioni dinamiche diverso da statici importazioni e su come utilizzarli.

Nella prima versione dell'app, il cucciolo vive in components/Puppy.js. A visualizza il cucciolo sulla pagina, l'app importa il componente Puppy in index.js con un'istruzione di importazione statica:

import Puppy from "../components/Puppy";

Per verificare in che modo Next.js raggruppa l'app, controlla la traccia di rete in DevTools:

  1. Per visualizzare l'anteprima del sito, premi Visualizza app. Quindi premi Schermo intero schermo intero.

  2. Premi "Ctrl+Maiusc+J" (o "Comando+Opzione+J" su Mac) per aprire DevTools.

  3. Fai clic sulla scheda Rete.

  4. Seleziona la casella di controllo Disabilita cache.

  5. Ricarica la pagina.

Quando caricherai la pagina, tutto il codice necessario, incluso Puppy.js è raggruppato in index.js:

Scheda DevTools Network in cui sono visualizzati sei file JavaScript: index.js, app.js, webpack.js, main.js, 0.js e il file dll (Dynamic-link Library).

Quando premi il pulsante Fai clic qui, viene richiesta solo la richiesta per il cucciolo JPEG aggiunte alla scheda Rete:

Scheda DevTools Network dopo il clic sul pulsante, che mostra gli stessi sei file JavaScript e un'immagine.

Lo svantaggio di questo approccio è che anche se gli utenti non fanno clic sul pulsante vedere il cucciolo, deve caricare il componente Puppy perché è incluso index.js. In questo piccolo esempio non è un grosso problema, ma in realtà per le applicazioni, è spesso un enorme miglioramento caricare componenti di grandi dimensioni solo necessaria.

Ora dai un'occhiata a una seconda versione dell'app, in cui l'importazione statica sostituita con un'importazione dinamica. Next.js include next/dynamic, che lo rende possibile utilizzare importazioni dinamiche per qualsiasi componente in Next:

import Puppy from "../components/Puppy";
import dynamic from "next/dynamic";

// ...

const Puppy = dynamic(import("../components/Puppy"));

Segui i passaggi del primo esempio per ispezionare la traccia di rete.

Quando carichi per la prima volta l'app, viene scaricato solo index.js. Questa volta è 0,5 kB più piccolo (è sceso da 37,9 kB a 37,4 kB) perché non include il codice per il componente Puppy:

La rete DevTools che mostra gli stessi sei file JavaScript, ad eccezione del fatto che il file index.js è ora più piccolo di 0,5 kB.

Il componente Puppy ora si trova in un blocco separato, 1.js, che viene caricato solo quando premi il pulsante:

Scheda DevTools Network dopo il clic sul pulsante, che mostra il file 1.js aggiuntivo e l'immagine aggiunta in fondo all'elenco dei file.

Nelle applicazioni reali, i componenti sono spesso molto più grandi e tramite caricamento lento ridurre il payload JavaScript iniziale di centinaia di kilobyte.

Importazioni dinamiche con indicatore di caricamento personalizzato

Quando esegui il caricamento lento delle risorse, è buona norma fornire un indicatore di caricamento. in caso di ritardi. In Next.js, puoi farlo fornendo un argomento aggiuntivo alla funzione dynamic():

const Puppy = dynamic(() => import("../components/Puppy"), {
  loading: () => <p>Loading...</p>
});

Per vedere l'indicatore di caricamento in azione, simula una connessione di rete lenta in DevTools:

  1. Per visualizzare l'anteprima del sito, premi Visualizza app. Quindi premi Schermo intero schermo intero.

  2. Premi "Ctrl+Maiusc+J" (o "Comando+Opzione+J" su Mac) per aprire DevTools.

  3. Fai clic sulla scheda Rete.

  4. Seleziona la casella di controllo Disabilita cache.

  5. Nell'elenco a discesa Limitazione, seleziona 3G rapido.

  6. Premi il pulsante Fai clic qui.

Ora, quando fai clic sul pulsante ci vuole un po' di tempo per caricare il componente e l'app visualizza il messaggio "Caricamento in corso..." nel frattempo.

Una schermata scura con il testo

Importazioni dinamiche senza SSR

Se devi eseguire il rendering di un componente solo sul lato client (ad esempio, un widget) puoi farlo impostando l'opzione ssr su false:

const Puppy = dynamic(() => import("../components/Puppy"), {
  ssr: false,
});

Conclusione

Grazie al supporto delle importazioni dinamiche, Next.js fornisce il codice a livello di componente la suddivisione, in modo da ridurre al minimo i payload JavaScript e migliorare il tempo di caricamento. Per impostazione predefinita, tutti i componenti hanno il rendering lato server e puoi disattivare questa opzione quando necessario.