先定数再动手:vibe 项目的性能预算实战
没有预算,优化永远做不完也守不住。本文讲第一版性能预算怎么定、怎么写进 CI 门禁、超标时四种还法怎么选、AI 功能为什么要单独算,附上线验收清单。

以下示例产品与人物均为虚构:示例产品叫“青柠记账”,是一个一人开发的记账小工具;示例人物周远是它的开发者。本文讲的方法可以套用到任何一人或小团队项目上,数字是举例用的参考值,不是行业标准,你要按自己的用户和设备情况定。
很多 vibe 项目不是慢在技术上,而是慢在没人提前说清楚“多慢算不能接受”。周远的“青柠记账”就是这样:第一版只有记账和看报表,打开很快;后来加了图表库、加了图片识别、加了分享海报,首页从一秒多涨到四秒多,用户开始抱怨,评论区有人说“打开一次要等半天,干脆不用了”。周远去做优化,图片压了、代码拆了,首页回到两秒多,可下一次加功能又弹回去。他后来才明白,问题不在优化手段,而在于项目从头到尾没有一条性能预算:没有人规定首页最多多大、首屏最多等多久,于是每次加功能都默认“慢一点没关系”,慢一点攒多了就成了四秒。
性能预算就是给项目立的一条事先说好的线:某个页面在某种设备和网络下,最多用多少资源、最多等多久。它不是优化技巧的清单,而是一份事前协议。优化技巧回答“怎么变快”,预算回答“快到什么程度才算合格、超了怎么办”。没有预算,优化永远做不完,也永远守不住;有了预算,每次加功能都有一个可以对照的数,争论就从“感觉有点慢”变成“首屏预算是两秒,现在是两秒六,超了六百毫秒,我们砍哪一块”。
预算到底管哪几样东西
预算不用一开始就面面俱到,管住最影响用户感受的几样就够了。第一是首屏时间,也就是用户点开页面到能看懂内容要等多久。对内容型页面和工具型页面,这个数最值得先定,因为用户在首屏等的时候最容易走。第二是交互响应,也就是点按钮、切标签、输入数字之后,界面多久给反馈。记账这种高频操作的产品,点一下要等半秒以上,用户就会觉得“卡”,哪怕首屏很快。第三是包体积,也就是首屏要下载的 JavaScript 和样式一共多大。包越大,弱网和低端机上首屏越慢,而且这个数最容易在不知不觉中涨上去:加一个图表库涨几百 KB,加一个日期库又涨几十 KB。
第四是图片和媒体。图片经常是页面最重的东西,一张没压缩的截图就能顶好几个代码包。预算里要给图片单独留位置:首屏图片总大小、单张上限、是不是用了合适的尺寸和格式。第五是接口和 AI 等待。vibe 项目现在很多都接了 AI 功能,模型返回要几秒是常态,这一部分不能跟普通接口混在一起算:普通接口超时两秒算慢,AI 生成等五秒用户可能还能接受,前提是界面一直在给反馈,而不是一片空白干等。所以预算要分开写:普通接口有普通接口的数,AI 功能有 AI 功能的数,流式输出有流式输出的数。
周远给“青柠记账”定的第一版预算就是按这五样写的,一共只有六行:首页首屏在中端安卓机加普通 4G 网络下不超过两秒;点“记一笔”到弹窗出现不超过两百毫秒;首屏 JavaScript 不超过两百 KB;首屏图片合计不超过三百 KB;普通接口九成五在八百毫秒内返回;AI 记账识别十秒内给结果,且一秒内先出现“正在识别”的状态。六行不多,但每一行都能量、都能在发布前检查。预算贵精不贵多,写二十行没人记得住的预算,等于没有预算。
第一版预算怎么定才不拍脑袋
定预算最忌讳照抄别人的数字。别人的“首页两秒”是跑在旗舰机和光纤上的,你的用户可能在地铁里用千元机。正确顺序是先测自己的基线:拿一台你身边最普通、甚至有点旧的手机,连上节流后的网络,打开你现在的页面,记下首屏时间、包体积、图片大小。这个实测值就是起点,预算就定在比起点好一点、但踮脚能够到的地方。比如现在首屏是三秒二,预算定两秒五,而不是一步到位定一秒;先守住不恶化,再一版一版往前提。预算是拿来执行的,不是拿来贴墙上好看的,定一个永远达不到的数,只会让团队学会无视预算。
不同类型的项目,预算的侧重点也不一样。纯展示的个人主页,首屏时间和图片最重要,交互响应可以放宽一点;天天要点的记账、待办、打卡工具,交互响应和包体积更重要,因为用户每天打开好几次,每次慢半秒都会累积成烦躁;内容多、图片多的作品集或食谱站,图片预算要单独拎出来,宁可首屏少放两张图,也不要让一张大图拖垮整页。周远一开始给所有页面定同一个数,结果报表页怎么都达不到,最后他改成首页一套、报表页一套、设置页一套,报表页因为图表多,包体积预算放宽到三百 KB,但首屏时间预算不变,办法是图表按需加载:先出数字,再慢慢画图。预算分页面、分场景,才是能落地的预算。
还有一个容易忽略的点:预算要写清楚测试条件。同样一个页面,在办公室 Wi-Fi 下测是一秒,在节流 4G 下测可能是三秒。预算后面必须跟一句“在什么设备、什么网络下测”,否则以后每次争论都会变成“在我电脑上很快啊”。周远的预算文件里每一行都带条件,比如“中端安卓机、节流 4G、冷启动、清空缓存”。条件写死,测量才有可比性,超没超预算才吵得清楚。
把预算写进能拦住人的地方
预算只写在文档里,等于没写。最有效的办法是让预算变成发布流程里的一道关:每次改动在合并前跑一次检查,超预算就亮红灯。做法不用复杂,哪怕一开始只是手动跑几个命令、把结果贴在合并说明里,也比“大家自觉遵守”强。周远的做法是把预算写进仓库里的一个 performance-budget.json 文件,里面就是那六行数;每次发版前跑一次打包体积检查和一次真机节流测试,把结果跟文件里的数对照,超了就必须在发版说明里写清楚超了哪一项、为什么超、准备怎么还。文件的好处是看得见、改得了、有历史:以后有人问“这个数是谁定的、为什么是两秒”,翻提交记录就能找到。
等流程跑顺了,再把检查自动化。打包体积超了就让持续集成直接失败,这是最硬的一道关,因为包体积一超,基本是有人悄悄加了大依赖。首屏时间和接口时间可以先做成“警告”而不是“失败”,因为网络波动会让时间测量忽高忽低,直接拦发布容易误伤。周远的规则是:体积超了必拦,时间连续两次超了才拦,单次超标先记下来、下一版必须处理。这样既有约束力,又不会因为一次网络抖动就卡住发版。自动化不是为了为难自己,而是为了让“超预算”这件事不需要靠记忆和自觉。
预算文件还要规定一件事:谁有权改预算。预算不是刻在石头上的,产品长大了、用户换了设备、业务加了重功能,预算都应该跟着调。但改预算必须走明路:改哪一行、从多少改到多少、理由是什么,写进提交说明,并且至少让另一个人(哪怕是未来的自己)看得懂。最怕的是有人为了发版方便,悄悄把两秒改成四秒,改完还没人知道。周远给自己定的规矩是:放宽预算要单独提交、单独写理由,不许跟功能代码混在一次提交里。这一条帮他挡住了好几次“先放宽、以后再说”的冲动。
超预算了,四种还法怎么选
预算真正值钱的时候,不是定下来的那天,而是第一次超标的那天。周远第一次超标是加了分享海报功能:海报要用到一个绘图库,首屏包体积从一百九十 KB 涨到两百六十 KB,超了六十 KB。团队里常见的第一反应是“把预算放宽到三百 KB 吧,反正就这一次”,但“就这一次”多来几次,预算就名存实亡了。周远后来总结出四种还法,按顺序试:第一是砍功能,看新功能是不是真的要首屏就加载,海报功能完全可以等用户点“分享”时再加载绘图库,首屏体积一分不涨;第二是换方案,看有没有更轻的库、能不能用系统自带能力代替,比如日期处理能不能不用整个日期库,只写几个小函数;第三是分期加载,把不着急的东西拆到闲时或交互时再加载,首屏先给核心内容;第四才是放宽预算,而且放宽要附带代价说明:放宽到多少、影响哪些用户、准备在哪个版本还回来。
这四种还法排成顺序是有道理的:前三种是在预算内解决问题,第四种是承认预算要改。顺序反过来,先放宽再说,预算很快就变成橡皮筋。周远还给自己加了一条谈判模板,超标时必须回答四个问题:超了哪一项、超了多少、影响的是哪些用户和场景、不改的话用户会损失什么。拿海报功能举例,答案是:超了首屏包体积六十 KB,影响的是弱网用户首屏多等约半秒,不改的话用户分享一次要多等,但不影响记账主流程。四个问题答完,结论就很清楚了:海报库改成点击时加载,首屏预算不动。这个模板的价值在于把争论从“这个功能重不重要”拉回到“用户要多等多久、值不值”,而后者是能量出来的。
还有一种超标容易被忽略:不是一次加很多,而是一次加一点点。每个版本涨十 KB,十个版本就是一百 KB,谁都没觉得自己是罪魁祸首。对付这种慢涨,办法是给预算加一条“涨幅红线”:比如单次改动让首屏体积涨超过二十 KB,就必须在说明里解释;连续三个版本都在涨,哪怕每次都没超总预算,也要停下来复盘一次。周远的报表页就是这样被救回来的:连续三版各涨了一点,第三版结束时离预算只剩十 KB,他提前把图表换成了按需加载,而不是等到超标那天再手忙脚乱。预算管的不只是超没超,还管趋势往哪走。
AI 功能的预算要单独算
接了 AI 功能的项目,预算最容易在 AI 这一块失控。模型调用本身就慢,还不稳定:同一句话今天三秒、明天八秒,后端排队、限流、重试都会让时间忽上忽下。如果拿普通接口的八百毫秒去要求 AI 返回,结果只能是天天超标、天天被迫放宽,最后预算作废。正确做法是把 AI 预算拆成三段:第一段是“多久给反馈”,也就是用户点完之后,界面多久出现“正在生成”“正在识别”之类的状态,这个数要短,一秒以内最好,因为用户需要立刻知道系统收到了请求;第二段是“多久出首字或首批结果”,流式输出的项目尤其要定这个数,用户看到字一个一个往外冒,等待感会大幅下降;第三段才是“多久出完整结果”,这个数可以放宽到十秒甚至更久,但必须配上进度反馈和取消按钮,让用户随时能走。
AI 功能还有两个隐性成本要进预算:一是第三方脚本和模型服务带来的额外下载和等待,比如语音识别、图片生成要拉的模型文件或 SDK,别只算自己的代码包;二是失败和重试的成本,模型偶尔会超时、会返回空结果,预算里要留出重试一次的时间和界面状态,而不是假设每次调用都一次成功。周远的 AI 记账识别就是按三段写的预算:一点识别按钮,一秒内出现状态;三秒内开始流式回填识别到的金额和分类;十秒内出完整结果,超时自动给“再试一次”和“手动输入”两个出口。预算写到这个粒度,AI 功能才不会变成“反正 AI 就是慢”的法外之地。
另外提醒一句:AI 生成的图片、音频、长文本,体积和加载时间也要进预算。生成一张大图直接塞进首屏,前面省下来的包体积全白费。周远的做法是 AI 生成的图片先压到展示尺寸再上首屏,原图只在用户点开详情时再加载;长文本先出摘要或前几行,全文按需展开。预算的原则在 AI 时代没变:先给用户能用的东西,重的、慢的、贵的都往后放。
最常见的五个坑
第一个坑是在自己的电脑上测。开发机是旗舰配置、办公室网络又快,在上面测出来的数比真实用户快得多,预算定出来也偏乐观。解决办法是固定一台“最差可接受设备”当标尺,哪怕是身边一台用了三年的旧手机,预算就按它来定。第二个坑是只看平均值。平均首屏两秒,可能是九成用户一点五秒、一成用户六秒,平均数把最惨的那批用户藏起来了。预算要看分位数,至少看九成用户的数,条件允许再看九成五。第三个坑是预算写进文档就以为完事了,发布流程里没有任何检查,三个月后谁都忘了预算是多少。预算必须进文件、进检查、进发版说明,缺一环都会滑坡。
第四个坑是只定上线那天的预算,不管以后。产品会长大,预算也要定期复查:每个月或每几个版本花半小时看看趋势,是不是一直在往上限逼近、是不是某个页面长期顶着上限跑。顶着上限跑的页面,下一次加功能必超,不如提前处理。第五个坑是把预算当成惩罚工具,谁超标就批谁。预算的目的是让取舍有依据,不是让人不敢加功能。周远的经验是,超标讨论只谈数字和用户影响,不谈对错;放宽预算也不丢人,只要理由写清楚、代价说明白、还期定下来。预算让人敢做决定,而不是让人怕做决定。
上线前验收清单
发版之前,对着下面这张清单过一遍,比临时想起来要靠谱。第一,预算文件在不在仓库里,每一行有没有写测试条件;第二,首屏、交互、包体积、图片、接口、AI 六项有没有实测数据,而不是凭感觉;第三,超标项有没有按四种还法处理过,放宽的有没有写理由和还期;第四,弱网和旧设备测过没有,只在办公室 Wi-Fi 下测过的不算;第五,趋势看过没有,连续上涨的页面有没有提前处理;第六,失败和超时状态有没有预算,比如接口超时后界面多久给提示、AI 超时后有没有手动出口。六项都过,这一版的性能才算有交代。
最后说一句大实话:性能预算不是让你把项目做成跑分冠军,而是让你在“加功能”和“保体验”之间有一个事先说好的分界线。一人项目最缺的不是优化技巧,而是有人在加功能冲动上来的时候,拿出一条线说“慢到这里就停一停”。这条线不用多高大上,六行数、一个文件、一道发布检查就够了。先定下来,跑两个版本,再根据实测调一调,预算会在使用中越变越准。反过来,没有预算的项目,每次优化都是救火,每次加功能都是赌运气,赌赢几次之后,总有一次会输给用户的耐心。
评论 (0)
相关文章

一人项目最常见的死法不是做不出来,而是放下就拿不起来。本文讲复工手册五件套、怎么写给失忆的自己、AI 协作断档怎么接、复工第一天的固定顺序,附验收清单。

标签、分类、合集各干各的活,层级宁扁勿深,命名先定规矩再动手。本文讲标签体系怎么设计、怎么清理、谁有权新建,以及 AI 打标签之后为什么一定要有人复核,附上线验收清单。

动态流的价值不在记全,而在让人一眼看懂发生了什么重要的事。本文讲动态与通知、审计日志的分工,聚合分组、已读锚点、隐私边界、分页回溯与冷启动,以及写扩散与读聚合的取舍,附上线验收清单。