
有一次方案评审上,一个同事提了一个技术方案:用户在表单里填完信息,点提交,前端先把数据存到 localStorage,然后再异步发请求给后端。理由是 这样即使网络断了,用户的数据也不会丢。
方案讲完,其他人都在点头。
我问了一句:如果用户开了两个标签页,两个页面往同一个 localStorage 的 key 里写数据,后写的会覆盖先写的,你怎么处理?
他愣了三秒🤔。
然后我又问:localStorage 在 Safari 的无痕模式下写入会直接抛异常,你的 try/catch 在哪里?
他又愣了三秒🤔。
这个方案最终被重新设计了。不是因为我比他聪明,而是因为这两个坑我都真实踩过------第一个是在做多标签页同步时,第二个是在做跨境电商的移动端页面时。
技术判断力它不来自面试八股文,不来自技术博客,不来自任何课程。它来自你在生产环境里被坑过、被骂过、凌晨三点爬起来修过的那些事故🤷♂️。
技术判断力到底是什么?

当你看到一个技术方案时,你的脑子里会自动跑一遍这个方案在什么情况下会死的模拟。 弱网会不会挂?并发会不会乱?用户中途关掉页面会不会留下脏数据?Safari 会不会有兼容问题?安全边界在哪里?
这种模拟不是刻意的分析过程,而是一种近乎本能的条件反射。就像一个开了十年车的老司机,看到前面车的刹车灯亮了一下,脚已经移到刹车踏板上了------不需要经过 前车减速 → 我也应该减速 这个推理过程。
这种条件反射的形成,只有一个来源:你自己亲身经历过那个翻车的场景。
教你 5 个真实判断场景
以下 👇 每一个场景,都是教科书和面试题不会告诉你的。
方案看起来很优雅,但在弱网下会死,怎么办?
同事做了一个更新方案:用户点赞之后,前端先把 UI 改成已点赞状态,然后后台发请求。如果请求失败了,再把 UI 回滚。
这个方案在 Wi-Fi 环境下体验极好,用户感觉不到延迟。
但在弱网下------比如地铁里、电梯里、信号不好的会议室------请求不是成功或失败,而是长时间挂起。用户点了赞,UI 变了,等了 30 秒,请求超时,UI 回滚,用户看到点赞莫名其妙消失了。更糟的是如果用户在这 30 秒里又做了其他操作,回滚可能会把后续操作的状态也搞乱。
有判断力的前端会在方案里加这些东西👇

这些东西不在任何教程文章里。它们来自你在弱网环境下亲自被用户投诉过🤷♂️。
接口返回的数据都是对的?
后端同事说接口返回的用户列表里,avatar 字段一定有值。
没有判断力的前端会直接写 <img src={user.avatar} />。

有判断力的前端会追问一句:历史数据迁移过来的老用户有 avatar 吗?第三方登录过来的用户呢?注册了但没上传头像的呢?
然后他会写:
typescript
<img
src={user.avatar || DEFAULT_AVATAR}
onError={(e) => { e.currentTarget.src = DEFAULT_AVATAR }}
/>
这种怀疑不是对后端同事的不信任,是对线上真实数据复杂度的严谨。
这个方案只有在 demo 里跑得很好?
一个同事调研了一个 前端导出 Excel 的方案:用 SheetJS 在浏览器里生成 .xlsx 文件。Demo 里导出 100 行数据,秒出。
没有判断力的前端会说可以用。
有判断力的前端会问:

最终的判断是:超过 1000 行的导出,必须放到后端生成,前端只负责下载。 前端导出只用于小数据量的快速导出场景。
setTimeout 用了就完事了?
一个 自动保存 功能的方案:用户每次修改内容,setTimeout 延迟 3 秒后自动调接口保存。
看起来没毛病。
但有判断力的前端会想到:

正确的做法是 debounce + 请求队列 + 页面关闭前的 beforeunload 兜底。但更关键的判断是:自动保存这个功能本身就需要和产品经理对齐------用户期望的是每一次修改都不丢还是大部分时候不丢就行? 这两个预期对应的技术方案完全不同。
这个库 Github Star 很多,应该靠谱!
一个同事想引入一个 GitHub 上 8000 Star 的日期选择组件。
没有判断力的前端看 Star 数、看 README.md 里的截图,觉得可以。
有判断力的前端会打开这几样东西看👇

技术判断力是怎么长出来的?
说了这么多场景,核心问题来了:如果判断力来自经历,那是不是只能等着被坑才能成长?
不完全是。你可以刻意加速这个过程。
复盘每一次线上事故
我从 2019 年开始,每次经历或者听说一个线上事故,就在本地的 Markdown 文件里记一条。格式很简单:
markdown
### 2024-03-15 商品详情页白屏
- 现象:部分用户打开商品详情页白屏
- 原因:接口返回的 categoryPath 字段在某些老商品里是 null,
前端直接 .split('/') 报错
- 教训:任何接口返回的字符串字段,用之前先判空
- 关联:后端说这个字段一定有值,实际上老数据没有
几年下来,我的事故清单有 100 多条。每次做方案评审或者 Code Review 的时候,我脑子里跑的那个数据源就是这份清单。
或者主动去看别人的事故
不一定每个坑都要自己亲自踩。你可以看别人踩的坑。
GitHub上热门开源项目的 👉Postmortem(事后分析)- 公司内部的事故复盘文档(如果你能拿到的话)
- 技术社区里那些我遇到了一个奇怪的 Bug的帖子------这些帖子的评论区往往比任何教程都有价值
看的时候不要只看怎么修的,要重点看为什么当初没发现。每一个事故的根因分析里,都藏着一条未来可以复用的判断规则。
判断力的本质什么?
带了这么多年团队,我越来越觉得:区分一个 3 年经验的前端和一个 8 年经验的前端,不是看谁的代码写得更花,而是看谁见过更多的事故。
见过的线上事故越多,你的技术方案里就越少有盲区。你写的代码不一定最精致,但它在那些极端场景下不会崩------因为你提前就把那些场景堵住了😃
好了,今天就分享到这里吧
