建站资源3步瘦身,加载提速1.8倍
|
接口超时告警那一刻,我正蹲在茶水间扒拉微波炉里那盒冷透的咖喱鸡——叮一声响,手机就炸了,三个群同时@我,监控大盘上那条绿色的线一直在抖,跟心跳失常似的。 去年11月的事。不是大促,没压测,就是普普通通周三下午四点十七分,首页加载突然卡住,用户反馈像雪片,运维老张边接电话边往我工位走,嘴里还念着“缓存击穿?不可能啊,我们有互斥锁……”,结果他工位上那台老戴尔机箱嗡嗡响得像要起飞,风扇声盖过了键盘敲击——我后来才发现是他把散热硅脂刮掉一半重涂,以为能降温,其实更烫。 我原以为是CDN缓存没刷全,结果一查日志,刷得太快看不清,满屏都是206和304,中间插着两行ERROR,字都被滚动吞掉了。切到前端日志,发现首页居然在 onl oad 后又发了7次 /api/v1/site/config 接口,同一个字段,连着 fetch 三遍,最后两次连 requestID 都没带。你猜是谁改的?小杨,上周刚提了PR说“统一配置中心落地”,结果把 config.js 里的 fallback 逻辑删了,换成 try-catch 里硬写死的兜底对象——对象里塞了整套未压缩的图标SVG base64,42KB,base64解码完87KB。他改的时候还在群里发了个“终于干掉祖传 if-else”,没人拦。
文章配图,仅供参考 然后才是那三步。第一步砍掉静态资源冗余,不是删图片,是删那些从来没被 require 过的 .js 文件——光 node_modules 下就有9个包,名字叫 @xxx/ui-icons-pro-v2-beta-legacy-alpha-lite,连版本号都拼不全,但 build 时候全打进 vendor.chunk.js。第二步是合并请求:把原来 5 个独立接口,改成 /api/v1/site/bundle?fields=theme,nav,seo,footer,analytics——不是后端加接口,是我硬逼前端用 Promise.all 封装成单请求再解包。第三步最简单:所有 .svg 全转成 inline,.css 里 background: url() 的路径,替换成 data:image/svg+xml;base64,……。做完那天,首页 TTFB 缩了,首屏时间跌下去一块,加载提速1.8倍。不是我算的,是前端小周拿 Lighthouse 跑了三次,平均下来1.78,四舍五入喊1.8。谁在工位上打电话谈房租?是隔壁组的老李,周三下午三点四十一分开始讲“押金退不退”、“物业费谁交”,声音穿透隔断,说到“合同写了不可抗力”那会儿,我们正在复盘为什么 bundle 接口第一次响应比第二次慢400ms——最后发现是 nginx 的 keepalive_timeout 设成了 5s,第一个连接刚建好,第二个就复用不上,得重连。没人改,因为谁也不知道它设在哪。 我说它站得住,是因为优胜劣汰。不是算法优胜劣汰,是人:一个字段有人敢动,有人不敢动,有人动了没人敢验,有人验了没胆子回滚。那个 bundle 接口上线灰度那天,小杨偷偷在我背后看了三分钟,没说话,转身去修他自己的 icon 引用问题——他删了 base64,换成本地 SVG sprite,但忘了加 xlink:href 前缀,页面加载后图标全空,控制台报错:“Failed to execute 'use' on 'SVGSVGElement': The provided URL is not valid.”。我看见他盯着 devtools 面板愣了七秒,手指悬在键盘上没动。这比什么 APM 报表都清楚:人比代码诚实。 咖啡机坏了。从周二坏到周五,按钮亮绿灯,但水不出。运维老张说“主板通讯异常”,IT部说“等配件”。最后是实习生小赵拆开壳,拿牙刷蘸酒精刷了下排线接口,好了。现在她写的单元测试覆盖率是组里最高,因为她不敢信别人写的 mock 数据。 外卖筷子掉在地上,我捡起来擦了擦继续吃。这件事和提速没关系,但当时我盯着那根断成两截的竹筷想,我们拆的哪是资源,是信任链——信任前端不会发重复请求,信任后端不会返多余字段,信任构建工具真懂 tree-shaking。结果呢?构建工具连 package.json 里 “type”: “module” 都读错,把 ESM 写成 CJS 打包进浏览器,报错 SyntaxError: Unexpected token 'export'。上线前夜才爆出来,回滚时小周在 Slack 里打了三行字:“我本地跑的好好的”,“node --version 是 18.17”,“你们环境变量 PATH 里是不是混了 nvm 的旧 bin?”——没发出去,删了,换了一行:“已 revert bundle 接口,恢复原逻辑。” 自己不敢动的那块?schema-validator。我们所有 /site/config 的返回值校验靠一个叫 validateSiteConfig.js 的文件,里面手写正则判 logoUrl 格式,还留着注释 // TODO: 改用 JSON Schema。没人动,因为上次改完,线上跑了两天,用户头像上传成功但不显示,查出来是 validator 把 https:// 开头的地址全拦了,理由是“协议必须小写”,而前端构造 URL 用的是 new URL(…).href,返回大写 HTTPS。这事过去半年了,注释还在,正则也还在,只是加了条例外:if (url.startsWith('HTTPS://')) url = url.toLowerCase();——没人敢删那行,怕漏掉什么隐式转换场景。 我跟产品争执过一次,说 banner 配置里“跳转链接”字段该强制校验协议,她说“运营填错了关你什么事”,我回她“那他们填 javascript:alert(1) 你也上?”她没说话,扭头叫来前端加了个提示:“请填写 http 或 https 开头的链接”。提示文字加了,校验没加。现在首页有个 banner,点进去是白屏,console 里印着 Uncaught SyntaxError: Unexpected identifier。不是 XSS,是 eval 了一个空字符串,因为链接字段值是空格加换行符,trim() 忘写了。谁写的?三年前的外包,离职邮件里写着“代码已移交”。 下周我把 bundle 接口的字段列表收进一个 const SITE_BUNDLE_FIELDS = ['theme', 'nav', ...],放 utils 目录,不放 types。类型定义早扔了,TS 检查形同虚设,因为所有 response.data 都 cast 成 any 再取 key——否则泛型嵌套太多,VSCode 直接卡死。你要是想看原始 schema?记不清是哪次了,大概那个量级,git blame 里最后一笔 commit 是“fix lint”,作者邮箱后缀是 @qq.com。 所以别问我怎么提速。我只敢动看得见、删得掉、上线后五分钟内能回滚的三步。再多?先修好咖啡机,再让老李谈完房租,等小赵哪天顺手把 validateSiteConfig.js 里的 TODO 行删了——那时候再说。 (编辑:站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |


16年工程师亲测:建站资源优化提速3倍,存储省70%
建站资源零散?重构策划与整合双轨防御架构
