随着应用程序的增长和功能日益丰富,它们在本地开发或创建生产构建时可能会需要更多资源。
让我们探讨一些策略和技术,以优化 Next.js 中的内存并解决常见的内存问题。
拥有大量依赖项的应用程序会占用更多内存。
Bundle Analyzer 可以帮助您调查应用程序中可能可以移除的大型依赖项,以提升性能和内存使用。
experimental.webpackMemoryOptimizations从 v15.0.0 开始,您可以将 experimental.webpackMemoryOptimizations: true 添加到 next.config.js 文件中,以更改 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 build 或 next dev 命令时,在命令开头添加 NODE_OPTIONS=--inspect。这将使检查器代理在默认端口上暴露。
如果您希望在任何用户代码开始之前暂停,可以改用 --inspect-brk。当进程运行时,您可以使用 Chrome DevTools 等工具连接到调试端口,以记录和分析堆快照,查看哪些内存被保留。
从 14.2.0 开始,您还可以使用 --experimental-debug-memory-usage 标志运行 next build,以便更容易地获取堆快照。
在此模式下运行时,您可以随时向进程发送 SIGUSR2 信号,进程将获取堆快照。
堆快照将保存到 Next.js 应用程序的项目根目录中,并且可以加载到任何堆分析器(例如 Chrome DevTools)中,以查看哪些内存被保留。此模式尚不与 Webpack 构建工作器兼容。
有关更多信息,请参阅 如何记录和分析堆快照。
Webpack 构建工作器允许您在独立的 Node.js 工作器中运行 Webpack 编译,这将减少应用程序在构建过程中的内存使用量。
如果您的应用程序从 v14.1.0 开始没有自定义 Webpack 配置,则此选项默认启用。
如果您使用的是较旧版本的 Next.js 或有自定义 Webpack 配置,您可以通过在 next.config.js 中设置 experimental.webpackBuildWorker: true 来启用此选项。
须知:此功能可能不兼容所有自定义 Webpack 插件。
Webpack 缓存 将生成的 Webpack 模块保存在内存和/或磁盘中,以提高构建速度。这有助于提升性能,但也会增加应用程序的内存使用量以存储缓存数据。
您可以通过向应用程序添加自定义 Webpack 配置来禁用此行为:
/** @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类型检查可能需要大量内存,尤其是在大型项目中。
然而,大多数项目都有专门的 CI 运行器来处理这些任务。
当构建在“Running TypeScript”步骤期间出现内存不足问题时,您可以在构建期间禁用此任务:
/** @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请记住,这可能会因为类型错误而导致错误的部署。
我们强烈建议仅在静态分析完成后才将构建推广到生产环境。
如果您部署到 Vercel,可以查看暂存部署指南,了解如何在自定义任务成功后将构建推广到生产环境。
在构建过程中生成源映射会消耗额外的内存。
您可以通过在 Next.js 配置中添加 productionBrowserSourceMaps: false 和 experimental.serverSourceMaps: false 来禁用源映射生成。
当使用 cacheComponents 功能时,Next.js 在 next build 的预渲染阶段默认会使用源映射。
如果您在该阶段(“Generating static pages”之后)持续遇到内存问题,
您可以尝试通过在 Next.js 配置中添加 enablePrerenderSourceMaps: false 来禁用该阶段的源映射。
须知:某些插件可能会启用源映射,并可能需要自定义配置才能禁用。
Next.js v14.1.3 修复了使用 Edge 运行时时的内存问题。请更新到此版本(或更高版本)以查看它是否解决了您的问题。
Next.js 服务器启动时,它会将每个页面的 JavaScript 模块预加载到内存中,而不是在请求时加载。
此优化可以实现更快的响应时间,但代价是初始内存占用会更大。
要禁用此优化,请将 experimental.preloadEntriesOnStart 标志设置为 false。
import type { NextConfig } from 'next'
const config: NextConfig = {
experimental: {
preloadEntriesOnStart: false,
},
}
export default config/** @type {import('next').NextConfig} */
const config = {
experimental: {
preloadEntriesOnStart: false,
},
}
export default configNext.js 不会卸载这些 JavaScript 模块,这意味着即使禁用了此优化,如果所有页面最终都被请求,您的 Next.js 服务器的内存占用最终也会相同。