一觉醒来,大模型就帮我排查完页面性能问题

作者:candyTong日期:2026/4/29

最近遇到一个性能问题,我让大模型自己去处理,然后就去午休了,醒来之后,它还真的把问题找出来并修复了

先说结果

最终定位出来的根因是:

这个业务工作台的查询表单,把 Formily 的 form 实例塞进了带 devtools 的 Zustand store。

这件事在开发环境里会非常要命,因为 form 不是一个轻量对象,它里面带着大量字段状态、reaction、effect、schema 和联动信息。
一旦进了 store,又被 devtools 观察、快照、序列化,内存就会被瞬间放大。

如果把这里面的角色先拆开,其实更容易理解:

  • Formily form 是一个重量级运行时实例,里面不只是表单值,还带着字段树、联动关系和各种内部状态
  • Zustand store 适合放跨组件共享的轻量状态,比如布尔值、筛选条件、选中 id 这类数据
  • devtools 在开发环境下会持续记录 store 变化,所以一旦把重对象塞进去,调试链路里的成本也会跟着被放大

更准确地说,这里的问题不是“Zustand 绝对不能放 Formily 对象”,而是:

Formily form 这种重量级运行时实例,本来就不适合进会被 devtools 观察、快照和序列化的 store state;而 devtools 又把这个问题成倍放大了。

所以如果只问“主要是不是 devtools 的影响”,答案是:

  • 是,主要是 devtools 把问题放大了
  • 根上还是对象放错了位置
  • 就算没有 devtools,这种设计也依然不优雅,只是未必会炸得这么明显

修完之后,Playwright 复现出来的内存数据从:

  • 修复前:839MB ~ 887MB

变成了:

  • 修复后:165MB ~ 207MB

这里的数字来自页面里已有的内存日志采样,主要用来做同一场景下的前后对比,不是一份精确的 heap profile。

也就是说,那个最扎眼的“900MB 级内存高峰”,确实被打下来了。

问题是什么?

我做的是一个后台工作台页面,页面主体可以简单理解成三块:

  • 一块复杂的查询表单
  • 一块结果表格
  • 一块会反向改写查询条件的数据报表

也就是说,这不是一个“填完表单点搜索就结束”的页面,而是多个区域都会读写同一套查询状态。这也是为什么问题后来会收敛到 query form:当不同模块都想访问同一个表单实例时,最容易出现“顺手把 form 放进全局 store”这种设计。

最开始看到的问题很直接:

  • 页面一打开,内存就冲到 900MB 左右
  • 这个高内存不是闪一下就没了,而是会持续一段时间
  • 差不多要到 30 秒左右 才明显掉下来
  • 一热更新,页面还很容易直接崩掉
  • 切到别的页面时,也经常会被一起拖崩

这里先补一句:30 秒后会回落 这个现象确实存在,但这次排查的重点不是解释“它为什么回落”,而是先找出“为什么峰值会被顶到这么离谱”。因为哪怕后面会掉下来,开发态里先冲到 900MB 也已经足够把热更新和页面稳定性一起拖垮了。

用户自己已经先排过一轮,确认问题大概率和查询表单有关,所以这次不是从整页瞎猜,而是直接围着 query form 往下查。

我是怎么给大模型下指令的

这个业务工作台页面打开以后,内存一直很高,差不多 900MB,要到第 30 秒左右才掉下来。
我已经查到是查询表单导致的,但具体原因还没找到。
你直接用 Playwright 打开页面看看。

我给它的信息其实很朴素:页面是一个业务工作台页面,现象是内存大约 900MB、30 秒后才回落,已知范围是查询表单,证据入口是 bootstrap.tsx 里那段内存日志,要求它必须直接用 Playwright 打开页面去看,而不是只给我猜测。

这里的 bootstrap.tsx 不是一个神秘线索,它只是项目启动入口里原本就有一段内存日志,所以模型一上来就能先接住现成证据,而不是从零开始搭监控。

这类输入的核心不是“怎么把提示词写得像魔法”,而是:

把问题描述成一个可以执行、可以验证、可以收敛的任务。

大模型做了什么

它做的事情其实很像一个靠谱的前端同学在接手问题。

先用 Playwright 直接打开页面,不是先猜。它先拿 /index 做基线,确认首页内存大约在 110MB ~ 127MB,说明不是整个站点天然就高;再去打开这个业务工作台页面,很快就把异常复现出来了:内存一路冲到 839MB ~ 887MB,并且一直到 30 秒左右 才掉到 79MB 左右。到这一步,问题就从“感觉不对”变成了“机器也能稳定看到”。

这里的数字口径都来自同一套页面内存日志采样,重点是看同一页面、同一种采样方式下的前后差异,不是拿它去做跨页面的精确内存对账。

接着它没有在整页里乱翻,而是顺着“查询表单”继续往下查,很快就把链路串起来了:

  • 查询表单组件先创建了 Formily form
  • 为了让别的模块也能访问它,代码又把这个 form 实例写进了查询表单对应的 Zustand store
  • 这个 store 在开发环境下又接了 zustand/middleware/devtools

如果把这条链路翻译成人话,就是:

  1. 组件内部创建了一个很重的 form 运行时对象
  2. 为了跨模块共享,代码把它塞进了 store state
  3. store 又接了 devtools,所以这个重对象进入了调试链路
  4. devtools 在当前开发环境下会持续记录和处理这些 state 变化
  5. 于是问题就不再只是“内存里有一个重对象”,而是“这个重对象还被反复观察和放大”

根因也就很清楚了:Formily form 这种重量级运行时实例,本来就不适合放进会被 devtools 观察、快照和序列化的 store state;而 devtools 又把这个问题放大成了 900MB 级高峰。 所以这事不是“表单字段太多”,而是“重对象被放错了位置,而且被 devtools 放大了”。

确定根因之后,它没有停在“给建议”,而是直接把代码改了:修复前,查询表单把 Formily form 直接塞进 Zustand store state;修复后,store state 里只保留轻量的 hasForm,真正的实例改成闭包保存,通过 getForm() 按需读取,再把依赖 state.form 的地方一起改掉。

这里要注意,闭包保存实例 不是说这个对象突然就不存在了,而是说它不再进入 store state 的快照和调试链路。真正重新划清的边界是:

  • 适合进 store 的,是 hasForm、筛选条件、选中项、布尔状态这类轻量数据
  • 不适合进 store 的,是 Formily form、DOM 节点、带大量内部引用的运行时实例

这种改法本质上是在重新划清边界:轻状态进 store,重实例不要进会被调试链路持续观察的状态面。 当然,这也不代表把实例移出 state 就万事大吉了,后面依然要按组件生命周期处理好它的创建、读取和清理。

最后它又回到同一个页面,再用 Playwright 复验一遍。修完之后,页面打开时的内存降到了 165MB ~ 207MB,30 秒左右会进一步降到 96MB 左右。也就是说,这不是“看起来像修好了”,而是前后数据能直接对上。整个排查、修改和验证的闭环,大约就用了十来分钟

总结

这次最值得复用的,不是一条具体的性能结论,而是这套工作方式:让大模型配合浏览器,自己完成复现、排查、修改和验证。

如果以后你也想照着做,输入里至少要把几件事说清楚:

  • 页面和场景:到底是哪一页、哪个交互有问题
  • 现象和数据:比如内存到多少、持续多久、有没有日志
  • 已知边界:哪怕只是“大概率和查询表单模块有关”,也很有用,能帮大模型减少很多不必要的查询路径
  • 证据入口:日志文件、入口代码、复现路径
  • 闭环要求:别只让它分析,直接要求它用浏览器先复现,再定位,再修改,最后验证

如果你懒得自己组织,可以直接按这个最小模板来:

页面是一个带复杂查询联动的后台页面。
现象是页面打开后内存升到 900MB 左右,30 秒后才回落。
我已经确认问题大概率和查询表单有关。
证据入口是启动入口里的内存日志。
请你先用浏览器复现,再定位原因,改完以后给我修复前后的对比数据。

一句话说,这次真正能抄作业的地方就是:

把大模型当成一个会用浏览器、会自己验证结果的工程执行者,而不只是一个会聊天的分析助手。


一觉醒来,大模型就帮我排查完页面性能问题》 是转载文章,点击查看原文


相关推荐


打造工业级全栈文件管理器:深度解析上传、回收站与三重下载流控技术
微特尔普拉斯2026/4/20

在构建企业级 Web 应用时,文件管理器是一个看似简单实则充满挑战的模块。面对大文件上传卡顿、大文件下载导致浏览器崩溃、以及误删不可恢复等痛点,我们需要一套更科学的架构方案。 本文将通过 Vue 2/3 + Spring Boot 的组合,详细拆解如何实现一套具备:排重检测、多线程后台下载、流式下载进度监控、以及回收站机制的文件管理系统。 一、 核心技术原理分析 1. 智能冲突检测上传 在上传文件前,系统会先发起一个“预检请求”(Check Exists)。 原理:前端获取文件名


一文搞懂Harness Engineering与Meta-Harness
GreenTea2026/4/12

一、什么是Harness Engineering harness engineering目前没有官方的英文翻译,但是我认为“驾驭工程”非常合适。“驾驭”一词本身有两层含义,“释放”与“约束”这两个相辅相成的维度,打个形象的比方,跟古代君臣关系一样,既要委以重任,又要设立制衡。 我们可以将这两层含义拆解如下: 1.1 释放潜力:让 AI 像工程师一样“真刀真枪”地干活 把模型放到现场,赋予了工程现场的实权,像一个工程师一样干活,能够接触代码库、执行命令,释放模型的潜力 传统的 Copilot


大模型应用开发学习第一天
程序员雷欧2026/4/4

从今天开始,雷欧将和大家一起学习大模型应用开发。我们不搞基础,不搞虚的,只搞最重要的知识来学习。         今天,我们要学习的是Transformer架构!!当然,底层机理,包括代码实现,并不需要我们知道,那么,我们需要学会什么呢?咱接着往下看……         首先,简单介绍一下什么是Transformer,Transformer是一种基于纯注意力机制的神经网络架构,由谷歌在2017年提出,最初用于机器翻译任务,现在已成为NLP和CV领域的基础架构。 1.Transformer整


腾讯云WorkBuddy实战, 全场景智能体工作搭子,这只龙虾真能帮你干活吗
不惑_2026/3/26

全网都在养虾。 朋友圈被刷屏了。同事也在搞。连高盛的分析师都惊了,说中国人接受AI的速度令人震惊。 但说实话,在我真正装上WorkBuddy之前,我是持怀疑态度的。 之前OpenClaw火的时候,很多人的真实体验是,折腾三小时,报错二十次,连命令行都没跑起来。一个面向普通人的AI工具,如果连安装都搞不定,那跟没有有什么区别? 所以当腾讯说WorkBuddy零部署、下载就能用的时候, 我第一反应是,真的假的。 ▲ WorkBuddy桌面端主界面,打开就是一个对话框,简洁到有点不像腾讯的风格 装上


JavaScript 中 Map 的完整解析
小李子呢02112026/3/18

Map 是 ES6 新增的键值对集合类型,专门用于解决普通对象({})作为键值存储的痛点(比如键只能是字符串 / 符号、无法直接获取长度等)。 1. 核心特性 特性说明键的类型可以是任意类型(数字、字符串、布尔值、对象、函数、null/undefined)遍历顺序严格按照插入顺序遍历(普通对象不保证)长度获取直接通过 map.size 获取(普通对象需手动计算 Object.keys(obj).length)键的唯一性同一个键只能存一个值(重复设值会覆盖)内存 / 性能存储大量键值对时,Ma


动态规划 线性 DP 经典四题一遍吃透
乌萨奇也要立志学C++2026/3/10

文章目录 台阶问题最大子段和传球游戏乌龟棋 线性dp 是动态规划问题中最基础、最常⻅的⼀类问题。它的特点是状态转移只依赖于前⼀个或前⼏个状态,状态之间的关系是线性的,通常可以⽤⼀维或者⼆维数组来存储状态。 我们在⼊⻔阶段解决的《下楼梯》以及《数字三⻆形》其实都是线性dp,⼀个是⼀维的,另⼀个是⼆ 维的。 台阶问题 题目描述 题目解析 本题就是上一节下楼梯的问题的加强版,总体思路不变,下面我们还是按照动规5板斧来分析一下这道题。 1、状态表示 dp[i]表示走到


一款使用 C# 编写专为 Windows 11 打造的文件资源管理器增强工具!
追逐时光者2026/3/2

前言 在 Windows 11 中,文件资源管理器虽已支持标签页,但默认行为仍会打开多个独立窗口,容易造成桌面混乱。今天大姚给大家分享一款专为 Windows 11 打造的文件资源管理器增强工具:ExplorerTabUtility,它能够自动将新打开的资源管理器窗口转换为标签页,助您实现更简洁、更有条理的文件管理体验。 工具介绍 ExplorerTabUtility 是一款使用 C# 编写专为 Windows 11 文件资源管理器设计的增强型工具,开源免费(MIT license),旨在解决原


AGENTS.md 真的对 AI Coding 有用吗?或许在此之前你没用对?
恋猫de小郭2026/2/22

AGENTS.md 相信大家应该不陌生,它们一般都是被放在根目录的典型 Context Files ,这些文件被默认作为 Coding Agnet 的 「README」,一般是用来提供仓库概览、工具链指令、编码规范或者设计模式等,不少 Agent 还提供 /init 之类命令自动生成这些文件。 实际上在此之前大家都是 GEMINI.md 、CLAUDE.md 、copilot-instructions.md 之类的各自为政,而 2025 之后,OpenAI、谷歌、Cursor 和 Source


【机器学习:逻辑回归】
Keep__Fighting2026/2/13

【逻辑回归】 1、简介 我们知道回归任务一般是处理线性问题的,预测结果是连续的,分类任务是结果是离散的。对于分类问题,在传统的机器学习算法中有很多解决方法,这里讲一下众多思想,其中之一——逻辑回归。 逻辑回归(Logistic Regression)通过将线性回归的输出映射到(0,1)区间,得到一个概率值,通过设定阈值的方式达到分类的效果,在此之中,使用Sigmoid函数将连续值转换为概率值,也即使用Sigmoid映射线性结果到(0,1)之间。 2、激活函数(概率映射) 在逻辑回归中,除了使用s


Slidev:开发者专属的演示文稿神器
修己xj2026/2/5

最近我在逛GitHub时,发现了一个很有意思的项目——Slidev。如果用一句话来总结,那就是: 用 Markdown 写幻灯片,让技术分享更高效、更优雅。 今天就来给大家推荐一下这个项目。 ❓为什么选择 Slidev? 作为开发者,我们经常需要做技术分享、产品演示或会议报告。传统的演示工具(如 PowerPoint、Keynote)虽然功能强大,但对于代码展示和实时编程演示往往力不从心。这就是 Slidev 诞生的原因——专为开发者设计的演示文稿工具。 Slidev(Slide + de

首页编辑器站点地图

本站内容在 CC BY-SA 4.0 协议下发布

Copyright © 2026 XYZ博客