优化 Next.js 应用的内存使用

应用不断增长、功能变得更丰富时,本地开发和生产构建可能需要更多资源。下面介绍优化内存使用、排查 Next.js 常见内存问题的一些策略和方法。

减少依赖数量

依赖很多的应用会使用更多内存。Bundle Analyzer 可以帮助查找大型依赖,评估是否能够移除它们,以改善性能和内存占用。

尝试 experimental.webpackMemoryOptimizations

从 v15.0.0 开始,可以在 next.config.js 中添加 experimental.webpackMemoryOptimizations: true。这会改变 Webpack 的行为,降低峰值内存占用,但可能略微增加编译时间。

此功能仍处于实验阶段,以便先在更多项目上测试。官方将其描述为风险较低的实验功能;实际项目效果仍需验证。

运行带内存调试参数的构建

从 14.2.0 开始,可以运行 next build --experimental-debug-memory-usage。在该模式下,Next.js 会在整个构建过程中持续输出内存信息,包括堆使用量和垃圾回收统计。内存使用接近配置上限时,也会自动生成堆快照。

此功能不兼容 Webpack build worker。没有自定义 Webpack 配置时,build worker 通常会自动启用。

记录堆分析文件

可以让 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 build 或 next dev 时,在命令前加上 NODE_OPTIONS=--inspect,会在默认端口启用 inspector agent。如果希望在任何用户代码运行前暂停,可改用 --inspect-brk。进程运行期间,可用 Chrome DevTools 等工具连接调试端口,记录和分析堆快照,了解哪些内存仍被保留。

从 14.2.0 开始,也可以给 next build 加上 --experimental-debug-memory-usage,更方便地获取堆快照。在该模式下,可以随时向进程发送 SIGUSR2 信号,让进程保存堆快照。快照文件会写入 Next.js 项目的根目录,可以加载到 Chrome DevTools 等堆分析工具中查看。此模式目前还不兼容 Webpack build worker。

更多说明见 记录与分析堆快照。调试端口与堆文件可能包含应用内部数据,使用时应限定可访问范围;不同操作系统对环境变量和信号的支持需要按实际运行环境核查。

Webpack build worker

Webpack build worker 可以在独立的 Node.js worker 中执行 Webpack 编译,降低构建时应用的内存使用量。从 v14.1.0 开始,没有自定义 Webpack 配置的应用会默认启用此选项。

使用更旧的 Next.js 版本或自定义 Webpack 配置时,可以在 next.config.js 中设置 experimental.webpackBuildWorker: true 启用它。

此功能可能不兼容某些自定义 Webpack 插件。上面的 Webpack 选项不应直接视为 Turbopack 的配置。

关闭 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',
      })
    }
    // Important: return the modified config
    return config
  },
}

export default nextConfig

此示例把生产构建缓存调整为内存类型,并未让所有 Webpack 缓存彻底消失。标题沿用原文,应以代码实际行为为准;修改配置后必须返回 config。

关闭构建期间的静态分析

类型检查可能使用大量内存,尤其是在大型项目中。不过,许多项目已有专门的 CI runner 执行这些任务。如果构建在 “Running TypeScript” 阶段发生内存耗尽,可以在构建期间关闭该任务:

next.config.mjs:

/** @type {import('next').NextConfig} */
const nextConfig = {
  typescript: {
    // !! WARN !!
    // Dangerously allow production builds to successfully complete even if
    // your project has type errors.
    // !! WARN !!
    ignoreBuildErrors: true,
  },
}

export default nextConfig

参见 Ignoring TypeScript Errors。这样可能把存在类型错误的版本部署出去。强烈建议只有静态分析完成后,才把构建提升到生产环境。使用 Vercel 时,可参考暂存与生产部署指南,在自定义检查成功后再提升构建。

关闭 source map

构建时生成 source map 会消耗额外内存。可以在 Next.js 配置中加入 productionBrowserSourceMaps: false 与 experimental.serverSourceMaps: false,关闭相应的 source map 生成。

Next.js 默认在 next build 的预渲染阶段使用 source map。如果总是在该阶段,也就是 “Generating static pages” 之后遇到内存问题,可以尝试加入 enablePrerenderSourceMaps: false,在这一阶段关闭 source map。

某些插件会开启 source map,可能需要分别修改其配置。

Edge 内存问题

Next.js v14.1.3 修复了一个 Edge runtime 内存问题。可以更新到该版本或更新版本,检查是否解决了你遇到的问题。

预加载入口

Next.js 服务器启动时会把各页面的 JavaScript 模块预加载到内存中,而不是等到收到请求时再加载。这样可以缩短响应时间,但启动时的内存占用更高。

要关闭此优化,把 experimental.preloadEntriesOnStart 设为 false。

TypeScript,next.config.ts:

import type { NextConfig } from 'next'

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

JavaScript,next.config.mjs:

/** @type {import('next').NextConfig} */
const config = {
  experimental: {
    preloadEntriesOnStart: false,
  },
}

export default config

Next.js 不会卸载这些 JavaScript 模块。因此,即使关闭了预加载,如果所有页面最终都被访问,服务器最终的内存占用仍会达到同样的水平。

原文:Next.js 文档团队,How to optimize memory usage;同页文档源文件。Copyright (c) 2025 Vercel, Inc. 文档源文件随仓库按 MIT 许可发布。本版本翻译为中文,并补充了构建器适用范围、调试数据保护及缓存示例行为提示;代码保持原样,未运行构建或采集快照。

MIT 完整许可
The MIT License (MIT)

Copyright (c) 2025 Vercel, Inc.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容