Lazy Loading (Nachträgliches Laden)

Lazy Loading (Nachträgliches Laden) in Next.js hilft, die anfängliche Ladeleistung einer Anwendung zu verbessern, indem die Menge an JavaScript reduziert wird, die zum Rendern einer Route benötigt wird.

Es ermöglicht Ihnen, das Laden von Client-Komponenten (Client Components) und importierten Bibliotheken zu verzögern und sie nur dann in das Client-Bundle einzubeziehen, wenn sie benötigt werden. Zum Beispiel könnten Sie das Laden eines Modals verzögern, bis ein Benutzer darauf klickt, um es zu öffnen.

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

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

Standardmäßig werden Server-Komponenten (Server Components) automatisch codegesplittet, und Sie können Streaming verwenden, um Teile der Benutzeroberfläche progressiv 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 anfänglichen JavaScript-Bundle der Seite enthalten sein. Die Seite rendert zuerst den Suspense-fallback, gefolgt von der Header-Komponente, wenn die Suspense-Grenze aufgelöst ist.

import dynamic from 'next/dynamic'

const DynamicHeader = dynamic(() => import('../components/header'), {
  loading: () => <p>Laden...</p>,
})

export default function Home() {
  return <DynamicHeader />
}

Gut zu wissen: In import('pfad/zur/komponente') muss der Pfad explizit angegeben werden. Es kann kein Template-String oder eine Variable sein. Darüber hinaus muss der import() innerhalb des dynamic()-Aufrufs stehen, damit Next.js Webpack-Bundles / Modul-IDs dem spezifischen dynamic()-Aufruf zuordnen und sie vor dem Rendern 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 funktioniert, ähnlich wie bei React.lazy.

Mit benannten Exports

Um einen benannten Export dynamisch zu importieren, können Sie ihn aus dem von import() zurückgegebenen Promise zurückgeben:

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 SSR

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

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 Fuzzy-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
          // Dynamisch fuse.js laden
          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>
  )
}