2019年,我提交的第一个React应用代码里,有段注释写着「TODO:这里明显会卡,上线后再优化」。那个TODO至今还在。它没杀死项目,但每年吃掉团队47小时用来解释「为什么搜索要转3秒」。

性能不是功能,是地基。地基裂缝时,楼上每块砖都在撒谎。

第一年:我们以为慢是小事

第一年:我们以为慢是小事

团队当时6个人,MVP(最小可行产品)周期压到8周。首屏加载4.2秒,我写在周报里的是「可接受范围」。用户没投诉——因为根本没人用到需要加载的那一步。

种子轮到账后,我们开始堆功能。图片懒加载、虚拟列表、代码分割,这些词只在技术分享会上出现,从未进过排期。CTO的原话:「先让投资人看到按钮能点,比点得快重要」。

转折点在第11个月。一个500行的表格组件,在客户演示时彻底卡死。不是崩溃,是鼠标悬停后光标变成转圈,整整7秒。客户没发火,只是问:「你们这技术,能撑到我们上市吗?」

那晚我翻了Chrome DevTools的Performance面板,发现重渲染(Re-render)触发了1400次。不是数据量大,是我把状态更新写在了错误的生命周期里——一个新手React开发者都不会犯的错,被我以「能跑就行」的心态埋了300天。

第二年:还债比借钱贵6倍

第二年:还债比借钱贵6倍

重构决定做得很快,执行拖了4个月。不是懒,是不敢动。业务代码和性能优化代码像毛线团缠在一起,扯一根会断十根。

我们用了最笨的办法:新建分支,逐模块迁移。一个搜索功能,重写花了3周,原开发只用了2天。QA(质量保证)测出17个回归Bug,其中3个是用户去年就习惯了的「特性」。

产品经理在会上说:「用户觉得旧的慢但稳,新的快但怪」。我们花了额外2周做A/B测试,证明「快」确实能提升转化率——但只提升了3.7%,而重构成本是原开发的6.2倍。

这段经历让我改了代码审查(Code Review)的清单。现在第一条不是「功能对吗」,是「这行代码会让主线程卡住超过16毫秒吗」。16毫秒是浏览器一帧的预算,超了用户就能感知到卡顿。

第三年:我把性能预算写进需求文档

第三年:我把性能预算写进需求文档

2022年开始,每个功能PR(Pull Request,代码合并请求)必须附带Lighthouse评分。不是事后测,是CI(持续集成)流水线自动阻断:首屏分数低于90,直接拒绝合并。

团队有人反对,说「小功能没必要」。我放了组数据:过去18个月,「后期优化」工单占技术债务的34%,平均每个优化工单阻塞其他开发2.7天。

更隐蔽的成本在决策层。因为早期没做性能基建,我们错过了两个大客户——他们的IT审计要求首屏加载低于2秒。不是技术做不到,是合同签下来后,我们给不出时间表。

现在我的新习惯:任何涉及列表、搜索、图表的需求,第一版设计稿必须标注「预期最大数据量」和「目标交互延迟」。产品经理学会了问「如果10万条数据呢」,而不是「能不能先跑起来」。

一个还在运行的TODO

一个还在运行的TODO

开头提到那个2019年的TODO,我上个月又看到了。它所在的模块现在服务于8000个企业客户,重写风险太高。我们做了折中:加了个加载动画,把「转3秒」包装成「数据安全保障中」。

用户满意度调研里,这条体验的评分是2.8/5。没人投诉,因为竞品更慢。

这是我最怕的胜利——用市场的不敏感,掩盖技术的懒惰。如果2019年有人告诉我「性能债的利息是复利」,我可能会把那个TODO的优先级标高一级。也可能不会。毕竟那时候,活下来比活得好重要。

你现在代码库里, oldest的TODO是哪一年写的?它还在产生利息吗?