后台系统用久了越来越卡,尤其是"数据看板"页面,首屏加载 4s+。产品催了三次"能不能快点"。
我用 AI 帮我分析了 bundle 和 render 性能,定位到 5 个问题组件,逐个优化。首屏从 4.2s 降到 2.5s。
分析过程
Step 1:Bundle 分析
# rsbuild 自带 bundle 分析npmrun build:prod ----analyzeAI 拿到 bundle 分析结果后给出的判断:
包体积 TOP 5(值得优化的): ──────────────────────────────────────── 模块 大小 占比 加载方式 echarts 1.2MB 22% 同步 ❌ @antv/g2 800KB 14% 同步 ❌ moment (遗留) 300KB 5% 同步 ❌ lodash (全量) 70KB 1.2% 同步 ⚠️ wangeditor 500KB 9% 同步 ❌ ──────────────────────────────────────── 以上合计 2.87MB,占总包 51% 问题:这些库不是每个页面都用,但被打进了主 bundle 方案:按路由动态 importStep 2:按路由拆分
// 改造前:同步导入importDataDashboardfrom'@/view/dashboard'importRichEditorfrom'@/view/marketing/editor'// 改造后:动态导入constDataDashboard=lazy(()=>import('@/view/dashboard'))constRichEditor=lazy(()=>import('@/view/marketing/editor'))但光路由拆分不够——echarts 在 5 个不同页面都用了,还是会被打进公共 chunk。
Step 3:AI 建议的深度拆分策略
// echarts 按需导入(从 500KB 降到 150KB)// 改造前import*asechartsfrom'echarts'// 改造后import*asechartsfrom'echarts/core'import{BarChart,LineChart,PieChart}from'echarts/charts'import{GridComponent,TooltipComponent,LegendComponent}from'echarts/components'import{CanvasRenderer}from'echarts/renderers'echarts.use([BarChart,LineChart,PieChart,GridComponent,TooltipComponent,LegendComponent,CanvasRenderer])// lodash 按需导入// 改造前import{debounce,throttle,cloneDeep}from'lodash'// 改造后importdebouncefrom'lodash/debounce'importthrottlefrom'lodash/throttle'importcloneDeepfrom'lodash/cloneDeep'Step 4:渲染性能分析
bundle 优化后首屏 JS 加载快了,但交互还是卡。AI 建议用 React Profiler 分析:
数据看板页面 render 瀑布: ──────────────────────────────────────── 组件 render 次数 耗时 DashboardHeader 1 5ms SalesChart 3 ❌ 120ms OrderTable 3 ❌ 200ms RealTimeStats 8 ❌ 40ms×8 FilterPanel 1 10ms ──────────────────────────────────────── 问题: - SalesChart 和 OrderTable 渲染了 3 次(父组件 state 变化导致重渲染) - RealTimeStats 有定时刷新但没做 memoStep 5:组件级优化
// 问题:父组件任何 state 变化都导致图表重渲染// SalesChart 渲染一次要 120ms(echarts 初始化)// 解决方案 1:React.memoconstSalesChart=memo(({data}:{data:SalesData[]})=>{// 只有 data 变化才重渲染return<ReactECharts option={getOption(data)}/>})// 解决方案 2:useMemo 缓存图表配置constSalesChart=({data}:{data:SalesData[]})=>{constoption=useMemo(()=>getOption(data),[data])return<ReactECharts option={option}/>}// 解决方案 3:RealTimeStats 的定时刷新隔离constRealTimeStats=memo(()=>{const[stats,setStats]=useState<Stats>()useEffect(()=>{consttimer=setInterval(async()=>{constres=awaitfetchRealTimeStats()setStats(res.data)},10_000)return()=>clearInterval(timer)},[])// 自己管理 state,不影响父组件return<StatCards data={stats}/>})优化效果汇总
优化项 优化前 优化后 提升 ────────── ────── ────── ──── 主 bundle 大小 5.6MB 2.1MB -62% 首屏 JS 加载 2.8s 1.2s -57% Dashboard 首屏渲染 4.2s 2.5s -40% 图表交互响应 300ms 50ms -83% 路由切换 800ms 200ms -75%AI 在性能优化中的角色
AI 做得好的: ├── 根据 bundle 分析结果判断哪些包该动态加载 ├── 给出 echarts/lodash 按需导入的具体写法 ├── 分析组件重渲染原因 + 给出 memo/useMemo 方案 ├── 生成优化前后对比的配置代码 └── 提供 rsbuild splitChunks 配置建议 AI 做不到的: ├── 实际运行 Profiler 看数据(需要你手动操作) ├── 判断业务上这个组件能不能 memo(可能有隐式依赖) ├── 衡量"值不值得优化"(需要你定优先级) └── 线上真实用户的性能数据收集Rsbuild 分包配置(AI 建议的最终版)
performance:{chunkSplit:{strategy:'custom',splitChunks:{cacheGroups:{// antd 单独打包(几乎所有页面都用)antd:{test:/[\\/]node_modules[\\/](antd|@ant-design)[\\/]/,name:'antd',chunks:'all',priority:30,},// echarts 单独打包(按需加载)echarts:{test:/[\\/]node_modules[\\/](echarts|zrender)[\\/]/,name:'echarts',chunks:'async',// 只在用到时才加载priority:20,},// 其他第三方vendors:{test:/[\\/]node_modules[\\/]/,name:'vendors',chunks:'all',priority:10,},},},},}什么时候该做性能优化
值得优化的信号: ├── 用户反馈"慢"(感知 > 3s 就算慢) ├── bundle 超过 3MB(SPA 的警戒线) ├── 某个页面首屏 > 3s ├── 交互有明显卡顿(输入延迟、滚动卡) └── Lighthouse 性能分 < 60 不需要过早优化的: ├── 没有用户投诉 ├── 内部工具(用户能接受 2-3s) ├── 页面本身就不复杂 └── 团队人力紧张(先做功能)💬 你们项目的 bundle 有多大?首屏加载时间是多少?有做过性能优化吗?
🔗完整 Skills 源码已开源:github.com/sleepyccat/ai-native-workflow,欢迎 Star ⭐ 和 PR。