用 AI 做性能分析:一行命令找出拖慢页面的 5 个组件,优化后首屏快了 40%

用 AI 做性能分析:一行命令找出拖慢页面的 5 个组件,优化后首屏快了 40%

后台系统用久了越来越卡,尤其是"数据看板"页面,首屏加载 4s+。产品催了三次"能不能快点"。

我用 AI 帮我分析了 bundle 和 render 性能,定位到 5 个问题组件,逐个优化。首屏从 4.2s 降到 2.5s。

分析过程

Step 1:Bundle 分析

bash 复制代码
# rsbuild 自带 bundle 分析
npm run build:prod -- --analyze

AI 拿到 bundle 分析结果后给出的判断:

matlab 复制代码
包体积 TOP 5(值得优化的):
────────────────────────────────────────
模块                      大小       占比      加载方式
echarts                   1.2MB      22%       同步 ❌
@antv/g2                  800KB      14%       同步 ❌
moment (遗留)             300KB      5%        同步 ❌
lodash (全量)             70KB       1.2%      同步 ⚠️
wangeditor               500KB      9%        同步 ❌
────────────────────────────────────────
以上合计 2.87MB,占总包 51%

问题:这些库不是每个页面都用,但被打进了主 bundle
方案:按路由动态 import

Step 2:按路由拆分

typescript 复制代码
// 改造前:同步导入
import DataDashboard from '@/view/dashboard'
import RichEditor from '@/view/marketing/editor'

// 改造后:动态导入
const DataDashboard = lazy(() => import('@/view/dashboard'))
const RichEditor = lazy(() => import('@/view/marketing/editor'))

但光路由拆分不够------echarts 在 5 个不同页面都用了,还是会被打进公共 chunk。

Step 3:AI 建议的深度拆分策略

typescript 复制代码
// echarts 按需导入(从 500KB 降到 150KB)
// 改造前
import * as echarts from 'echarts'

// 改造后
import * as echarts from '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])
typescript 复制代码
// lodash 按需导入
// 改造前
import { debounce, throttle, cloneDeep } from 'lodash'

// 改造后
import debounce from 'lodash/debounce'
import throttle from 'lodash/throttle'
import cloneDeep from 'lodash/cloneDeep'

Step 4:渲染性能分析

bundle 优化后首屏 JS 加载快了,但交互还是卡。AI 建议用 React Profiler 分析:

diff 复制代码
数据看板页面 render 瀑布:
────────────────────────────────────────
组件                      render 次数    耗时
DashboardHeader           1              5ms
SalesChart                3 ❌           120ms
OrderTable                3 ❌           200ms
RealTimeStats             8 ❌           40ms×8
FilterPanel               1              10ms
────────────────────────────────────────

问题:
- SalesChart 和 OrderTable 渲染了 3 次(父组件 state 变化导致重渲染)
- RealTimeStats 有定时刷新但没做 memo

Step 5:组件级优化

typescript 复制代码
// 问题:父组件任何 state 变化都导致图表重渲染
// SalesChart 渲染一次要 120ms(echarts 初始化)

// 解决方案 1:React.memo
const SalesChart = memo(({ data }: { data: SalesData[] }) => {
  // 只有 data 变化才重渲染
  return <ReactECharts option={getOption(data)} />
})

// 解决方案 2:useMemo 缓存图表配置
const SalesChart = ({ data }: { data: SalesData[] }) => {
  const option = useMemo(() => getOption(data), [data])
  return <ReactECharts option={option} />
}

// 解决方案 3:RealTimeStats 的定时刷新隔离
const RealTimeStats = memo(() => {
  const [stats, setStats] = useState<Stats>()

  useEffect(() => {
    const timer = setInterval(async () => {
      const res = await fetchRealTimeStats()
      setStats(res.data)
    }, 10_000)
    return () => clearInterval(timer)
  }, [])

  // 自己管理 state,不影响父组件
  return <StatCards data={stats} />
})

优化效果汇总

erlang 复制代码
优化项                    优化前      优化后      提升
──────────                ──────      ──────      ────
主 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 在性能优化中的角色

bash 复制代码
AI 做得好的:
├── 根据 bundle 分析结果判断哪些包该动态加载
├── 给出 echarts/lodash 按需导入的具体写法
├── 分析组件重渲染原因 + 给出 memo/useMemo 方案
├── 生成优化前后对比的配置代码
└── 提供 rsbuild splitChunks 配置建议

AI 做不到的:
├── 实际运行 Profiler 看数据(需要你手动操作)
├── 判断业务上这个组件能不能 memo(可能有隐式依赖)
├── 衡量"值不值得优化"(需要你定优先级)
└── 线上真实用户的性能数据收集

Rsbuild 分包配置(AI 建议的最终版)

typescript 复制代码
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,
        },
      },
    },
  },
}

什么时候该做性能优化

arduino 复制代码
值得优化的信号:
├── 用户反馈"慢"(感知 > 3s 就算慢)
├── bundle 超过 3MB(SPA 的警戒线)
├── 某个页面首屏 > 3s
├── 交互有明显卡顿(输入延迟、滚动卡)
└── Lighthouse 性能分 < 60

不需要过早优化的:
├── 没有用户投诉
├── 内部工具(用户能接受 2-3s)
├── 页面本身就不复杂
└── 团队人力紧张(先做功能)

💬 你们项目的 bundle 有多大?首屏加载时间是多少?有做过性能优化吗?


🔗 完整 Skills 源码已开源 :github.com/sleepyccat/...,欢迎 Star ⭐ 和 PR。

相关推荐
jktantan1 天前
Vue keep-alive 切标签后滚动位置回顶?因为 onDeactivated 里读到的 scrollTop 是 0
前端·javascript·vue.js
许雪里1 天前
XXL-AI v1.4.0 发布|AI应用开发平台
agent·ai编程
2601_962885721 天前
quotes 字段全解:涨跌幅、振幅、换手率的口径与单位
java·前端·spring
excel1 天前
encodeURI 和 encodeURIComponent 有什么区别?
前端
前端精髓1 天前
调用openrouter的免费API模型
java·前端·javascript
EnCi Zheng1 天前
Agent 如何进行工具调用:从一次 Function Calling 到生产级工具编排的完整链路
大数据·人工智能·agent·ai编程·工具调用
赛博守夜人1 天前
AI安全攻防与治理之十四:AI 安全测试不能脱离传统安全,Web、API、移动端与模型攻击面的组合拳
前端·人工智能·安全
开开心心_Every1 天前
快速隐藏程序工具自定义快捷键一键切换
java·开发语言·前端·spring·智能手机·word·intellij-idea
networknomad1 天前
OpenReplay:自己搭的会话回放工具,给前端排错用的
前端·其他
狼爷1 天前
AI正在制造通缩:一场闭门会背后,三个被大多数人忽略的底层逻辑
人工智能·aigc·ai编程