Menu

内存使用

随着应用程序变得更加功能丰富,它们在本地开发或创建生产构建时可能会需要更多资源。

让我们探讨一些策略和技巧来优化内存并解决 Next.js 中常见的内存问题。

减少依赖数量

拥有大量依赖项的应用程序会使用更多内存。

Bundle Analyzer 可以帮助你调查应用程序中可能可以移除以提高性能和减少内存使用的大型依赖项。

尝试 experimental.webpackMemoryOptimizations

v15.0.0 开始,你可以在 next.config.js 文件中添加 experimental.webpackMemoryOptimizations: true 来更改 Webpack 的行为,这可以减少最大内存使用量,但可能会略微增加编译时间。

值得注意的是:这个功能目前是实验性的,以便在更多项目上进行测试,但被认为是低风险的。

使用 --experimental-debug-memory-usage 运行 next build

14.2.0 开始,你可以运行 next build --experimental-debug-memory-usage 来以一种模式运行构建,在这种模式下 Next.js 会在整个构建过程中持续打印出内存使用信息,比如堆使用情况和垃圾回收统计。当内存使用接近配置的限制时,还会自动进行堆快照。

值得注意的是:这个功能与 Webpack 构建工作器选项不兼容,除非你有自定义的 webpack 配置,否则该选项会自动启用。

记录堆配置文件

要查找内存问题,你可以从 Node.js 记录堆配置文件,并将其加载到 Chrome DevTools 中以识别潜在的内存泄漏源。

在你的终端中,在启动 Next.js 构建时向 Node.js 传递 --heap-prof 标志:

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

在构建结束时,Node.js 将创建一个 .heapprofile 文件。

在 Chrome DevTools 中,你可以打开 Memory 标签并点击 "Load Profile" 按钮来可视化该文件。

分析堆快照

你可以使用检查工具来分析应用程序的内存使用情况。

运行 next buildnext dev 命令时,在命令开头添加 NODE_OPTIONS=--inspect。这将在默认端口上暴露检查代理。 如果你希望在任何用户代码开始之前中断,你可以传递 --inspect-brk 代替。当进程运行时,你可以使用 Chrome DevTools 等工具连接到调试端口,记录并分析堆的快照,以查看正在保留哪些内存。

14.2.0 开始,你还可以使用 --experimental-debug-memory-usage 标志运行 next build,这可以更容易地进行堆快照。

在此模式下运行时,你可以随时向进程发送 SIGUSR2 信号,进程将进行堆快照。

堆快照将保存到 Next.js 应用程序的项目根目录,可以在任何堆分析器(如 Chrome DevTools)中加载,以查看保留了哪些内存。此模式目前还不兼容 Webpack 构建工作器。

有关更多信息,请参阅如何记录和分析堆快照

Webpack 构建工作器

Webpack 构建工作器允许你在单独的 Node.js 工作器中运行 Webpack 编译,这将减少构建期间应用程序的内存使用。

v14.1.0 开始,如果你的应用程序没有自定义 Webpack 配置,默认情况下会启用此选项。

如果你使用的是旧版本的 Next.js 或者你有自定义的 Webpack 配置,你可以通过在 next.config.js 中设置 experimental.webpackBuildWorker: true 来启用此选项。

值得注意的是:此功能可能与所有自定义 Webpack 插件不兼容。

禁用 Webpack 缓存

Webpack 缓存将生成的 Webpack 模块保存在内存和/或磁盘中,以提高构建速度。这可以 帮助提高性能,但也会增加应用程序的内存使用量以存储缓存数据。

你可以通过向应用程序添加自定义 Webpack 配置来禁用此行为:

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",
      });
      config.cache.maxMemoryGenerations = 0;
    }
    // 重要:返回修改后的配置
    return config;
  },
};
 
export default nextConfig;

禁用静态分析

类型检查和代码检查可能会消耗大量内存,尤其是在大型项目中。然而,大多数项目都有专门的 CI 运行器来处理这些任务。当构建在"检查代码规范和类型有效性"步骤中出现内存不足问题时,你可以在构建过程中禁用这些任务:

next.config.mjs
/** @type {import('next').NextConfig} */
const nextConfig = {
  eslint: {
    // 注意:这允许生产构建在项目存在 ESLint 错误的情况下仍能成功完成。
    ignoreDuringBuilds: true,
  },
  typescript: {
    // !! 警告 !!
    // 危险地允许生产构建在项目存在类型错误的情况下仍能成功完成。
    // !! 警告 !!
    ignoreBuildErrors: true,
  },
}
 
export default nextConfig

请注意,由于类型错误或代码检查问题,这可能会导致部署出现故障。我们强烈建议仅在静态分析完成后才将构建部署到生产环境。如果你部署到 Vercel,可以查看暂存部署指南,了解如何在自定义任务成功后将构建部署到生产环境。

禁用源映射

生成源映射会在构建过程中消耗额外的内存。

你可以通过在 Next.js 配置中添加 productionBrowserSourceMaps: falseexperimental.serverSourceMaps: false 来禁用源映射生成。

值得注意的是:一些插件可能会开启源映射,可能需要自定义配置来禁用。

Edge 内存问题

Next.js v14.1.3 修复了使用 Edge 运行时时的内存问题。请更新到此版本(或更高版本)以查看是否解决了你的问题。