如何分析 Next.js 应用的打包体积?(Bundle Analysis)
分析 Next.js 应用的打包体积(Bundle Size)是性能优化的关键步骤。最常用且官方推荐的工具是 @next/bundle-analyzer。
以下是完整的步骤指南,从安装配置到如何分析及优化。
第一步:安装工具
首先,你需要安装 @next/bundle-analyzer 插件。为了跨平台(Windows/Mac/Linux)设置环境变量,建议同时安装 cross-env。
npm install @next/bundle-analyzer cross-env --save-dev
# 或者
yarn add -D @next/bundle-analyzer cross-env
# 或者
pnpm add -D @next/bundle-analyzer cross-env
第二步:配置 next.config.js
修改你的 next.config.js 文件,使用 withBundleAnalyzer 包裹现有的配置。
// next.config.js
const withBundleAnalyzer = require('@next/bundle-analyzer')({
enabled: process.env.ANALYZE === 'true', // 只有当环境变量 ANALYZE 为 true 时才开启
})
/** @type {import('next').NextConfig} */
const nextConfig = {
// 这里是你原本的 Next.js 配置
reactStrictMode: true,
// ...其他配置
}
module.exports = withBundleAnalyzer(nextConfig)
注意: 如果你已经使用了其他插件(如 next-pwa 等),可以进行链式调用或嵌套包裹。
第三步:添加分析脚本
在 package.json 的 scripts 中添加一个新的命令,专门用于分析构建:
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"analyze": "cross-env ANALYZE=true next build"
}
第四步:运行分析
在终端运行以下命令:
npm run analyze
运行结束后,Next.js 会执行构建过程,并自动在浏览器中打开两个网页:
client.html: 客户端 bundle 分析图(这是你最需要关注的,因为它影响用户下载速度)。server.html: 服务端 bundle 分析图(影响服务器启动速度和无服务器函数的冷启动时间)。
第五步:如何解读分析图
打开的页面是一个交互式的 Treemap(树图):
- 方块大小:代表文件的大小。方块越大,占用的体积越大。
- 颜色:通常用于区分不同的 chunk。
- 层级:你可以点击方块放大查看内部的具体模块。
- 左侧侧边栏:
- Stat size: 原始文件大小(未压缩、未转换)。
- Parsed size: Webpack 处理后的大小(如去除了空格、变量重命名等)。
- Gzipped size: 这是最重要的指标,代表经过 Gzip 压缩后,用户实际通过网络下载的大小。
你需要寻找的问题点:
- 巨大的
node_modules:是否有单个库占据了巨大的面积?(例如lodash,moment,xlsx等)。 - 重复打包:同一个库是否出现在了多个 chunk 中?
- 意外引入:是否引入了只在服务端使用的库(如
fs,database drivers)却被打包到了客户端代码中?
第六步:常见优化策略
根据分析结果,你可以采取以下措施:
1. 替换大体积库 (Replace heavy libraries)
- Moment.js -> 替换为
dayjs或date-fns(Moment.js 不支持 Tree Shaking,体积很大)。 - Lodash -> 确保使用按需引入
import get from 'lodash/get'或者使用lodash-es。
2. 动态导入 (Lazy Loading / Dynamic Imports)
如果某个组件很大(例如富文本编辑器、复杂的图表库、3D 模型查看器),但不是首屏必须的,使用 Next.js 的 dynamic 进行懒加载。
import dynamic from 'next/dynamic'
const HeavyChart = dynamic(() => import('../components/HeavyChart'), {
loading: () => <p>Loading...</p>,
ssr: false, // 如果不需要服务端渲染,可以关闭
})
这样,该组件的代码会被分割到一个单独的 chunk 中,只有当组件渲染时才会被下载。
3. 检查 Barrel Files (索引文件)
如果你有一个 utils/index.js 导出了所有工具函数,而在页面中只用了一个,某些配置不当的情况下可能会导致所有工具函数都被打包。确保 Tree Shaking 正常工作。
4. 优化第三方脚本
使用 next/script 并配置加载策略(如 strategy="lazyOnload" 或 strategy="worker"),避免阻塞主线程。
其他辅助工具
除了 @next/bundle-analyzer,还有以下工具可以辅助分析:
Next.js Build Output (终端输出):
当你运行npm run build时,终端会显示每个页面的 First Load JS 大小。- 🟢 绿色: 小于 128kB (优秀)
- 🟡 黄色: 大于 128kB (警告)
- 🔴 红色: 大于 500kB (严重,必须优化)
Import Cost (VS Code 插件):
在编写代码时,该插件会直接在import语句旁显示引入包的大小,帮助你在开发阶段就意识到体积问题。Webpack Bundle Analyzer (独立版):
如果你需要更深度的 Webpack 配置分析,或者不使用 Next.js 的封装,可以直接配置 Webpack 的插件,但在 Next.js 中通常推荐使用官方封装版。
总结
- 安装
@next/bundle-analyzer。 - 配置
next.config.js。 - 运行
ANALYZE=true next build。 - 观察
client.html中的大方块。 - 针对性地进行库替换或动态导入。