Menu

Lazy Loading

Lazy Loading in Next.js hilft, die initiale Ladeperformance einer Anwendung zu verbessern, indem die Menge an JavaScript, die zum Rendering einer Route benötigt wird, verringert wird.

Es ermöglicht Ihnen, das Laden von Client-Komponenten und importierten Bibliotheken zu verzögern und sie nur dann in den Client-Bundle aufzunehmen, wenn sie benötigt werden. Beispielsweise möchten Sie das Laden eines Modals möglicherweise verzögern, bis ein Benutzer darauf klickt.

Es gibt zwei Möglichkeiten, Lazy Loading in Next.js zu implementieren:

  1. Verwendung von Dynamic Imports mit next/dynamic
  2. Verwendung von React.lazy() mit Suspense

Standardmäßig werden Server-Komponenten automatisch code split, und Sie können Streaming verwenden, um Teile der Benutzeroberfläche schrittweise vom Server an den Client zu senden. Lazy Loading gilt für Client-Komponenten.

next/dynamic

next/dynamic ist eine Kombination aus React.lazy() und Suspense. Es verhält sich in den Verzeichnissen app und pages gleich, um eine schrittweise Migration zu ermöglichen.

Beispiele

Durch die Verwendung von next/dynamic wird die Header-Komponente nicht im ursprünglichen JavaScript-Bundle der Seite enthalten sein. Die Seite rendert zunächst den Suspense-fallback, gefolgt von der Header-Komponente, wenn die Suspense-Grenze aufgelöst wird.

import dynamic from 'next/dynamic'
 
const DynamicHeader = dynamic(() => import('../components/header'), {
  loading: () => <p>Lädt...</p>,
})
 
export default function Home() {
  return <DynamicHeader />
}

Gut zu wissen: In import('path/to/component') muss der Pfad explizit geschrieben werden. Es kann kein Vorlagenliteral oder eine Variable sein. Außerdem muss das import() innerhalb des dynamic()-Aufrufs erfolgen, damit Next.js webpack-Bundles/Modulkennungen mit dem spezifischen dynamic()-Aufruf abgleichen und vor dem Rendering vorladen kann. dynamic() kann nicht innerhalb des React-Renderings verwendet werden, da es auf der obersten Ebene des Moduls markiert werden muss, damit das Vorladen ähnlich wie bei React.lazy() funktioniert.

Mit benannten Exports

Um einen benannten Export dynamisch zu importieren, können Sie ihn von der Promise zurückgeben, die von import() zurückgegeben wird:

components/hello.js
export function Hello() {
  return <p>Hallo!</p>
}
 
// pages/index.js
import dynamic from 'next/dynamic'
 
const DynamicComponent = dynamic(() =>
  import('../components/hello').then((mod) => mod.Hello)
)

Ohne Server-Side Rendering

Um eine Komponente clientseitig dynamisch zu laden, können Sie die Option ssr verwenden, um serverseitiges Rendering zu deaktivieren. Dies ist nützlich, wenn eine externe Abhängigkeit oder Komponente auf Browser-APIs wie window angewiesen ist.

'use client'
 
import dynamic from 'next/dynamic'
 
const DynamicHeader = dynamic(() => import('../components/header'), {
  ssr: false,
})

Mit externen Bibliotheken

Dieses Beispiel verwendet die externe Bibliothek fuse.js für die unscharfe Suche. Das Modul wird nur im Browser geladen, nachdem der Benutzer in das Suchfeld eingegeben hat.

import { useState } from 'react'
 
const names = ['Tim', 'Joe', 'Bel', 'Lee']
 
export default function Page() {
  const [results, setResults] = useState()
 
  return (
    <div>
      <input
        type="text"
        placeholder="Suche"
        onChange={async (e) => {
          const { value } = e.currentTarget
          // Dynamisches Laden von fuse.js
          const Fuse = (await import('fuse.js')).default
          const fuse = new Fuse(names)
 
          setResults(fuse.search(value))
        }}
      />
      <pre>Ergebnisse: {JSON.stringify(results, null, 2)}</pre>
    </div>
  )
}