包分析与代码拆分策略
使用 rollup-plugin-visualizer 分析包体积,并按路由制定代码拆分策略。
包分析与代码拆分策略 是 CoddyKit 上的免费 React Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 React Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 React Academy 课程共包含 4 节课。
为什么包体积很重要
大型 JavaScript 包会延迟可交互时间。每 KB 的 JS 都必须先下载、解析并执行,页面才能变得可交互;在移动网络较慢时尤其如此。
使用 rollup-plugin-visualizer 分析
在 Vite 项目中,使用可视化插件生成包的树状图,查看哪些模块占用的空间最多。
// vite.config.ts
import { visualizer } from 'rollup-plugin-visualizer';
export default defineConfig({
plugins: [
visualizer({ open: true, gzipSize: true, brotliSize: true })
],
});
// After build, open the generated HTML file to explore the treemapNext.js 包分析器
使用 @next/bundle-analyzer 分析 Next.js 中的服务器包和客户端包。
npm install @next/bundle-analyzer
// next.config.js
const withBundleAnalyzer = require('@next/bundle-analyzer')({
enabled: process.env.ANALYZE === 'true',
});
module.exports = withBundleAnalyzer({});
// Run:
// ANALYZE=true npm run build基于路由的代码拆分
最有效的拆分方式是:只有在用户导航到某个路由时,才加载该路由的代码。React Router 的 lazy() 和 Next.js App Router 会自动执行此操作。
// React Router v6 with lazy loading
import { lazy, Suspense } from 'react';
const Dashboard = lazy(() => import('./pages/Dashboard'));
const Settings = lazy(() => import('./pages/Settings'));
<Routes>
<Route path="/dashboard" element={<Suspense fallback={<Loading />}><Dashboard /></Suspense>} />
<Route path="/settings" element={<Suspense fallback={<Loading />}><Settings /></Suspense>} />
</Routes>组件级代码拆分
使用 lazy() 将大型组件(地图、图表、编辑器)的加载延迟到真正需要它们时。
const MonacoEditor = lazy(() => import('@monaco-editor/react'));
const MapView = lazy(() => import('./MapView'));
function ProductEditor({ showMap }) {
return (
<>
<Suspense fallback={<EditorSkeleton />}><MonacoEditor /></Suspense>
{showMap && <Suspense fallback={<MapSkeleton />}><MapView /></Suspense>}
</>
);
}为条件功能使用动态导入
仅在某项功能被启用时才导入大型库,避免为所有用户加载这些库。
async function exportToPDF() {
const { default: jsPDF } = await import('jspdf'); // ~300KB — loaded on demand
const doc = new jsPDF();
doc.text('Hello', 10, 10);
doc.save('export.pdf');
}树摇
现代打包工具会移除未使用的导出(死代码)。确保您的依赖支持 ESM(而不是 CJS),这样树摇才能生效;当您只使用一个函数时,也不要导入整个库。
// Bad — imports entire lodash (~70KB):
import _ from 'lodash';
const result = _.debounce(fn, 300);
// Good — imports only debounce (<2KB):
import debounce from 'lodash/debounce';
// or with tree-shaking-friendly lodash-es:
import { debounce } from 'lodash-es';预加载关键 chunk
使用 <link rel='modulepreload'> 或 Webpack 魔法注释,在用户停留于当前页面时预加载下一页面的 chunk。
// Webpack magic comment — preload on hover:
const Dashboard = lazy(() => import(/* webpackPrefetch: true */ './Dashboard'));
// or preload (higher priority):
const Dashboard = lazy(() => import(/* webpackPreload: true */ './Dashboard'));分析第三方影响
在安装 npm 包之前,使用 bundlephobia.com 或 Import Cost VS Code 扩展查看其 gzip 压缩后的大小。
设置包体积预算
在 Webpack 或 Vite 配置中为每个路由设置大小限制。如果某个 chunk 超出预算,构建就会失败,从而在 CI 中发现意外的体积增长。
// vite.config.ts
build: {
rollupOptions: {
output: {
manualChunks: {
'vendor-react': ['react', 'react-dom'],
'vendor-router': ['react-router-dom'],
},
},
},
chunkSizeWarningLimit: 200, // warn at 200KB
},快速检查
对于包含许多页面的 React 单页应用,最有效的代码拆分策略是什么?
回顾
使用 rollup-plugin-visualizer 或 @next/bundle-analyzer 分析包。使用基于路由和组件级的 lazy() 拆分。只导入实际使用的内容,以应用树摇。在 CI 中设置大小预算,并使用预取/预加载提示来加载下一条最可能访问的路由。
常见问题解答
「包分析与代码拆分策略」课时是免费的吗?
是的 — 「包分析与代码拆分策略」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 React Academy 课程的其余内容,请升级到 CoddyKit PRO。 React Academy 课程共包含 4 节课。
「包分析与代码拆分策略」这节课中我会学到什么?
使用 rollup-plugin-visualizer 分析包体积,并按路由制定代码拆分策略。 你通过在浏览器中直接运行的动手代码来练习 React Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 React Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 React Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。
「包分析与代码拆分策略」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 React Academy 课中编写并运行代码吗?
能。每节 React Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。