如何优化本地开发环境

Next.js 旨在提供卓越的开发体验。随着应用程序规模增长,您可能会注意到本地开发时的编译速度变慢。本指南将帮助您识别并解决常见的编译性能问题。

本地开发与生产环境的区别

使用 next dev 的开发过程与 next buildnext start 有所不同。

next dev 会在您访问或导航到路由时进行即时编译。这样您无需等待所有路由编译完成即可启动开发服务器,既提高了速度又减少了内存占用。而生产环境构建会应用其他优化措施,如文件压缩和内容哈希生成,这些在本地开发中并不需要。

提升本地开发性能

1. 检查电脑杀毒软件

杀毒软件可能会拖慢文件访问速度。

尝试将项目文件夹添加到杀毒软件的排除列表中。虽然这在 Windows 电脑上更为常见,但我们建议所有安装了杀毒工具的系统都进行此项设置。

2. 更新 Next.js 并启用 Turbopack

确保您使用的是最新版 Next.js,每个新版本通常都包含性能改进。

Turbopack 是集成到 Next.js 中的新型打包工具,可以提升本地开发性能:

npm install next@latest
npm run dev --turbopack

详细了解 Turbopack。查看我们的升级指南和代码转换工具获取更多信息。

3. 检查导入方式

代码导入方式会显著影响编译和打包时间。了解更多关于优化包打包的技巧,并探索 Dependency CruiserMadge 等工具。

图标库

@material-ui/iconsreact-icons 这样的库可能会导入数千个图标,即使您只使用其中几个。建议仅导入需要的图标:

// 不要这样:
import { Icon1, Icon2 } from 'react-icons/md'

// 应该这样:
import Icon1 from 'react-icons/md/Icon1'
import Icon2 from 'react-icons/md/Icon2'

react-icons 等库包含多种图标集。选择一套图标集并坚持使用。

例如,如果您的应用同时导入以下图标集:

  • pi (Phosphor Icons)
  • md (Material Design Icons)
  • tb (tabler-icons)
  • cg (cssgg)

即使每个图标集只导入一个图标,编译器也需要处理数万个模块。

桶文件(Barrel files)

"桶文件"是指从其他文件导出大量内容的文件。它们会拖慢构建速度,因为编译器必须解析这些文件以确定模块范围内是否存在副作用。

尽可能直接从特定文件导入。了解更多关于桶文件的知识以及 Next.js 的内置优化。

优化包导入

Next.js 可以自动优化某些包的导入。如果使用包含桶文件的包,可将它们添加到 next.config.js

module.exports = {
  experimental: {
    optimizePackageImports: ['package-name'],
  },
}

Turbopack 会自动分析并优化导入,无需此配置。

4. 检查 Tailwind CSS 配置

使用 Tailwind CSS 时,请确保正确配置。

常见错误是在 content 数组中包含了 node_modules 或其他不应扫描的大型目录。

Tailwind CSS 3.4.8 或更高版本会对可能拖慢构建的设置发出警告。

  1. tailwind.config.js 中明确指定要扫描的文件:

    module.exports = {
      content: [
        './src/**/*.{js,ts,jsx,tsx}', // 正确做法
        // 这种范围可能过广
        // 会匹配到 `packages/**/node_modules`
        // '../../packages/**/*.{js,ts,jsx,tsx}',
      ],
    }
  2. 避免扫描不必要的文件:

    module.exports = {
      content: [
        // 更好做法 - 仅扫描 'src' 文件夹
        '../../packages/ui/src/**/*.{js,ts,jsx,tsx}',
      ],
    }

5. 检查自定义 webpack 配置

添加的自定义 webpack 设置可能会拖慢编译速度。

考虑是否真的需要在本地开发中使用这些配置。您可以仅在生产构建中包含某些工具,或考虑迁移到 Turbopack 并使用加载器

6. 优化内存使用

大型应用可能需要更多内存。

了解如何优化内存使用

7. 服务器组件与数据获取

服务器组件的更改会导致本地整个页面重新渲染以显示新变化,包括为组件获取新数据。

实验性选项 serverComponentsHmrCache 允许在本地开发中跨热模块替换 (HMR) 刷新缓存服务器组件的 fetch 响应。这能加快响应速度并减少计费 API 调用的成本。

了解此实验性选项

8. 考虑本地开发而非 Docker

如果在 Mac 或 Windows 上使用 Docker 进行开发,可能会遇到比本地运行 Next.js 显著更慢的性能。

在 Mac 和 Windows 上,Docker 的文件系统访问可能导致热模块替换 (HMR) 需要数秒甚至数分钟,而同一应用在本地开发时 HMR 速度很快。

这种性能差异源于 Docker 在非 Linux 环境下处理文件系统操作的方式。为获得最佳开发体验:

  • 开发阶段使用本地开发 (npm run devpnpm dev) 而非 Docker
  • 将 Docker 保留用于生产部署和测试生产构建
  • 必须使用 Docker 开发时,考虑在 Linux 机器或 VM 上使用 Docker

了解生产环境中的 Docker 部署

问题诊断工具

详细获取日志

next.config.js 中使用 logging.fetches 选项查看开发期间的详细信息:

module.exports = {
  logging: {
    fetches: {
      fullUrl: true,
    },
  },
}

了解获取日志详情

Turbopack 追踪

Turbopack 追踪工具可帮助您了解本地开发期间的应用程序性能。它提供每个模块编译时间及其关系的详细信息。

  1. 确保已安装最新版 Next.js

  2. 生成 Turbopack 追踪文件:

    NEXT_TURBOPACK_TRACING=1 npm run dev
  3. 在应用中导航或编辑文件以复现问题

  4. 停止 Next.js 开发服务器

  5. .next 文件夹中会出现名为 trace-turbopack 的文件

  6. 使用以下命令解析文件:

    next internal trace .next/trace-turbopack

    在未提供 trace 命令的版本中,使用:

    next internal turbo-trace-server .next/trace-turbopack
  7. 追踪服务器运行后,可在 https://trace.nextjs.org/ 查看结果

  8. 默认情况下追踪查看器会聚合时间数据,要查看单个时间点,可在查看器右上角将"Aggregated in order"切换为"Spans in order"

问题仍未解决?

将在 Turbopack 追踪 部分生成的追踪文件分享到 GitHub DiscussionsDiscord