Optimierung des Speicherverbrauchs

Wenn Anwendungen wachsen und funktionsreicher werden, können sie mehr Ressourcen bei der lokalen Entwicklung oder bei Produktions-Builds benötigen.

Lassen Sie uns einige Strategien und Techniken zur Optimierung des Speicherverbrauchs und zur Behebung häufiger Speicherprobleme in Next.js untersuchen.

Anzahl der Abhängigkeiten reduzieren

Anwendungen mit vielen Abhängigkeiten verbrauchen mehr Speicher.

Der Bundle Analyzer kann Ihnen helfen, große Abhängigkeiten in Ihrer Anwendung zu identifizieren, die möglicherweise entfernt werden können, um die Leistung und den Speicherverbrauch zu verbessern.

experimental.webpackMemoryOptimizations ausprobieren

Ab Version v15.0.0 können Sie experimental.webpackMemoryOptimizations: true in Ihrer next.config.js-Datei hinzufügen, um das Verhalten von Webpack zu ändern, das den maximalen Speicherverbrauch reduziert, aber die Kompilierungszeiten leicht erhöhen kann.

Gut zu wissen: Diese Funktion ist derzeit experimentell, um sie zunächst in mehr Projekten zu testen, gilt aber als risikoarm.

next build mit --experimental-debug-memory-usage ausführen

Ab Version 14.2.0 können Sie next build --experimental-debug-memory-usage ausführen, um den Build in einem Modus zu starten, in dem Next.js kontinuierlich Informationen über den Speicherverbrauch während des Builds ausgibt, wie z.B. Heap-Nutzung und Garbage-Collection-Statistiken. Heap-Snapshots werden auch automatisch erstellt, wenn der Speicherverbrauch nahe an das konfigurierte Limit heranreicht.

Gut zu wissen: Diese Funktion ist nicht kompatibel mit der Webpack-Build-Worker-Option, die standardmäßig aktiviert ist, es sei denn, Sie haben eine benutzerdefinierte Webpack-Konfiguration.

Heap-Profil aufzeichnen

Um Speicherprobleme zu untersuchen, können Sie ein Heap-Profil von Node.js aufzeichnen und es in Chrome DevTools laden, um potenzielle Quellen von Speicherlecks zu identifizieren.

Übergeben Sie in Ihrem Terminal das Flag --heap-prof an Node.js, wenn Sie Ihren Next.js-Build starten:

node --heap-prof node_modules/next/dist/bin/next build

Am Ende des Builds wird eine .heapprofile-Datei von Node.js erstellt.

In Chrome DevTools können Sie den Memory-Tab öffnen und auf den "Load Profile"-Button klicken, um die Datei zu visualisieren.

Heap-Snapshot analysieren

Sie können ein Inspector-Tool verwenden, um den Speicherverbrauch der Anwendung zu analysieren.

Wenn Sie den Befehl next build oder next dev ausführen, fügen Sie NODE_OPTIONS=--inspect am Anfang des Befehls hinzu. Dadurch wird der Inspector-Agent auf dem Standardport verfügbar gemacht. Wenn Sie den Prozess vor dem Start von Benutzercode unterbrechen möchten, können Sie stattdessen --inspect-brk übergeben. Während der Prozess läuft, können Sie ein Tool wie Chrome DevTools verwenden, um sich mit dem Debugging-Port zu verbinden und einen Snapshot des Heaps aufzuzeichnen und zu analysieren, um zu sehen, welcher Speicher belegt wird.

Ab Version 14.2.0 können Sie auch next build mit dem Flag --experimental-debug-memory-usage ausführen, um das Erstellen von Heap-Snapshots zu vereinfachen.

Während Sie in diesem Modus laufen, können Sie jederzeit ein SIGUSR2-Signal an den Prozess senden, und der Prozess wird einen Heap-Snapshot erstellen.

Der Heap-Snapshot wird im Projektstammverzeichnis der Next.js-Anwendung gespeichert und kann in jedem Heap-Analyzer, wie z.B. Chrome DevTools, geladen werden, um zu sehen, welcher Speicher belegt wird. Dieser Modus ist noch nicht mit Webpack-Build-Workern kompatibel.

Weitere Informationen finden Sie unter Heap-Snapshots aufzeichnen und analysieren.

Webpack-Build-Worker

Der Webpack-Build-Worker ermöglicht es Ihnen, Webpack-Kompilierungen in einem separaten Node.js-Worker auszuführen, was den Speicherverbrauch Ihrer Anwendung während des Builds verringert.

Diese Option ist standardmäßig aktiviert, wenn Ihre Anwendung ab Version v14.1.0 keine benutzerdefinierte Webpack-Konfiguration hat.

Wenn Sie eine ältere Version von Next.js verwenden oder eine benutzerdefinierte Webpack-Konfiguration haben, können Sie diese Option aktivieren, indem Sie experimental.webpackBuildWorker: true in Ihrer next.config.js setzen.

Gut zu wissen: Diese Funktion ist möglicherweise nicht mit allen benutzerdefinierten Webpack-Plugins kompatibel.

Webpack-Cache deaktivieren

Der Webpack-Cache speichert generierte Webpack-Module im Speicher und/oder auf der Festplatte, um die Geschwindigkeit von Builds zu verbessern. Dies kann die Leistung verbessern, erhöht aber auch den Speicherverbrauch Ihrer Anwendung, um die zwischengespeicherten Daten zu speichern.

Sie können dieses Verhalten deaktivieren, indem Sie Ihrer Anwendung eine benutzerdefinierte Webpack-Konfiguration hinzufügen:

next.config.mjs
/** @type {import('next').NextConfig} */
const nextConfig = {
  webpack: (
    config,
    { buildId, dev, isServer, defaultLoaders, nextRuntime, webpack }
  ) => {
    if (config.cache && !dev) {
      config.cache = Object.freeze({
        type: 'memory',
      })
    }
    // Wichtig: die modifizierte Konfiguration zurückgeben
    return config
  },
}

export default nextConfig

Statische Analyse deaktivieren

Typechecking und Linting können viel Speicher verbrauchen, insbesondere in großen Projekten. Die meisten Projekte haben jedoch einen dedizierten CI-Runner, der diese Aufgaben bereits übernimmt. Wenn der Build während des Schritts "Linting und Überprüfung der Typenvalidität" Speicherprobleme verursacht, können Sie diese Aufgaben während des Builds deaktivieren:

next.config.mjs
/** @type {import('next').NextConfig} */
const nextConfig = {
  eslint: {
    // Warnung: Dies ermöglicht es, dass Produktions-Builds erfolgreich abgeschlossen werden, auch wenn
    // Ihr Projekt ESLint-Fehler enthält.
    ignoreDuringBuilds: true,
  },
  typescript: {
    // !! WARNUNG !!
    // Erlaubt gefährlicherweise, dass Produktions-Builds erfolgreich abgeschlossen werden, auch wenn
    // Ihr Projekt Typfehler enthält.
    // !! WARNUNG !!
    ignoreBuildErrors: true,
  },
}

export default nextConfig

Beachten Sie, dass dies aufgrund von Typfehlern oder Linting-Problemen fehlerhafte Deployments produzieren kann. Wir empfehlen dringend, Builds erst dann in die Produktion zu überführen, nachdem die statische Analyse abgeschlossen ist. Wenn Sie auf Vercel deployen, können Sie die Anleitung für Staging-Deployments lesen, um zu erfahren, wie Sie Builds nach dem erfolgreichen Abschluss benutzerdefinierter Aufgaben in die Produktion überführen können.

Source Maps deaktivieren

Die Generierung von Source Maps verbraucht zusätzlichen Speicher während des Build-Prozesses.

Sie können die Generierung von Source Maps deaktivieren, indem Sie productionBrowserSourceMaps: false und experimental.serverSourceMaps: false zu Ihrer Next.js-Konfiguration hinzufügen.

Gut zu wissen: Einige Plugins können Source Maps aktivieren und erfordern möglicherweise eine benutzerdefinierte Konfiguration, um sie zu deaktivieren.

Speicherprobleme im Edge-Runtime

Next.js v14.1.3 hat ein Speicherproblem bei der Verwendung der Edge-Runtime behoben. Bitte aktualisieren Sie auf diese Version (oder höher), um zu sehen, ob es Ihr Problem löst.

Preloading von Einträgen

Wenn der Next.js-Server startet, lädt er die JavaScript-Module jeder Seite vorab in den Speicher, anstatt zur Laufzeit.

Diese Optimierung ermöglicht schnellere Antwortzeiten, erhöht aber den anfänglichen Speicherbedarf.

Um diese Optimierung zu deaktivieren, setzen Sie das Flag experimental.preloadEntriesOnStart auf false.

import type { NextConfig } from 'next'

const config: NextConfig = {
  experimental: {
    preloadEntriesOnStart: false,
  },
}

export default config

Next.js entlädt diese JavaScript-Module nicht, was bedeutet, dass selbst mit deaktivierter Optimierung der Speicherbedarf Ihres Next.js-Servers letztendlich derselbe sein wird, wenn alle Seiten irgendwann angefordert werden.