网页视觉优化:7个被技术人忽略的关键细节
|
凌晨三点十七分,告警系统在钉钉里炸了三轮——不是服务挂了,是前端监控里突然涌进三百七十二条“FCP > 3s”的埋点。我叼着没点着的烟蹲在工位上刷日志,DBA老张穿着拖鞋从机房出来,左脚那只鞋带松了,踩得地板啪嗒响。他路过我桌边顺手捞走我桌上半杯冷咖啡,喝了一口又呸地吐回纸杯里:“这玩意儿比我们库里那个死锁事务还苦。”
文章配图,仅供参考 我原以为又是 CDN 缓存没刷干净,结果切到 Lighthouse 跑了六遍,全卡在同一个地方:CSSOM 构建阶段的 style 标签嵌套层级——第十七层,没错,就是那个被后端硬塞进 HTML 的“兼容 IE11 的动态主题注入逻辑”,去年五月份上线的,当时说“只用一次”。现在它每次首屏都要重排三次,但没人敢动,因为动了登录页的 loading 动画会闪半帧。这个我敢打包票。空调嗡的一声,冷风突然加大。对面工位的工程师换了双新拖鞋,灰色绒面,鞋尖有点翘。他刚调完灰度开关,手机震了一下没接,屏幕亮着,显示是“行政-调休驳回通知”。我瞥了一眼,是他上个月二十八号夜班后申请的八小时调休,理由写的是“处理视觉抖动”,审批人栏里是老板亲笔写的“不批——先解决转化率问题”。可转化率根本没跌啊,跌的是用户停留时长,而我们还在埋首调按钮阴影深度。 第一个漏掉的细节:CSS 中 calc() 里混用了 rem 和 em。不是性能差,是它在 Safari 15.6 下触发 layout thrashing 的条件极其阴险——必须同时满足:① 页面有 iframe、② 用户开了阅读模式、③ 首次渲染前触发了 resize。我们线上跑了四个月才撞上这个组合,因为只有教培客户那个带 PDF 预览的弹窗会同时满足三条。我说不准是不是 Safari 自己的 bug,但我知道那个 calc(1rem + 1em) 我删掉之后,iOS 上的 TTI 缩短了十八秒——不是平均值,是 P95;而且只对启用了辅助字体缩放的用户生效。你去查监控平台,那块指标压根没打标,就叫“其他设备异常”。 第二个:font-display: swap 看似安全,但如果 font-family 名里含空格(比如 “PingFang SC”),某些 Chromium 版本会在加载未完成时 fallback 到系统默认等宽字体,且持续 400ms。不是 FOIT,不是 FOUT,是 FOUT+ 字体宽度突变+行高重算+整个段落 reflow —— 而我们的文案系统导出的字体名,永远带空格。这个坑是前端自己挖的,但填坑的时候没人告诉设计组,所以他们还在 AE 里调字间距,调了半年,不知道为啥始终对不齐。我见过三次线上 AB 测试失败,归因都是“设计稿还原度低”,没人往下查 CSS 的 @font-face 解析过程。 第三个:picture 标签里的 srcset 用了 x 描述符,但服务器返回的响应头里 Vary: User-Agent 没同步更新。结果 Cloudflare 缓存把 iPhone 13 的 3x 图缓存下来,喂给了 iPad Air 4 的 2x 屏——图片撑满,文字模糊,但页面尺寸一切正常。监控里只报“CLP 波动”,我们查了三天布局树,直到运维小陈半夜巡检 CDN 缓存键才发现 key 里 User-Agent 段没截断。他截图发群里,手指甲缝里全是黑的,估计刚换完交换机风扇。那张图我现在还记得:一个圆角为 8px 的卡片,在 iPad 上呈现成 12.3px —— 不是因为渲染误差,是因为 DPI 映射错了,像素对不上。 第四个……算了,这个不说也罢。反正上周我把它从 build pipeline 里删了,删完发现运营后台的 H5 转链页打开直接白屏。查了俩钟头,原来是某个第三方 SDK 在 window.__INJECTED_CONFIG 上塞了个 base64 编码的 SVG,而我们 webpack 的 mini-css-extract-plugin 正好把它当 CSS 变量解了,解到一半崩了。这事谁背锅?没人。只是那天值班表上写着我名字,所以告警群里的表情包全冲我来的。 第五个:focus-visible 的 polyfill。我们用了官方那个,但它会往每个 里加 tabindex="0",而我们有个老交互逻辑——所有按钮点击后触发 location.replace,结果 polyfill 一激活,键盘焦点跳转就变成两跳:先跳按钮,再跳地址栏,中间还闪一下 outline。测试同学录屏给体验组看,人家说“像癫痫发作”。我们改成了手动监听 focusin+ 用 :focus:not(:focus-visible),但文档里到现在还写着“已支持 focus-visible”。骗谁呢?连我们自己的自动化截图回归都没覆盖 tab 键路径。 第六个:SVG 内联样式里写了 transition: all .3s。对,就是那个在 header 里反复复用的 logo SVG。它没有 transform,没有 opacity,甚至没加 class,就光秃秃一句 style="transition:all .3s"。Chrome DevTools 的 Rendering Tab 里,这个元素始终挂着“强制同步布局”标记。问过三位前端,两个说“应该不影响”,一个说“可能和 viewBox 更新有关”。没人愿意 ssh 进 build 机器 grep 一遍 SVG 源码。我倒是 grep 了——找到 37 处,全在设计师传过来的 Sketch 导出物里。她们导出时勾了“包含 CSS 样式”,而我们 CI 里没做 strip。 第七个……其实不算细节。是我们压根没把视觉优化当“优化”,当成“UI 交付尾声的保洁”。优胜劣汰?没错,留下来的都是没出过大事故的,但没出事不等于没病。就像机房冷风常年开 22℃,谁也不知道里面那台旧 UPS 电容已经鼓包三年了,只是它坏的那天刚好没人在。 我明天早上九点跟老板拍桌子,就为了把“视觉性能基线”加进 MR check list。不为别的,就为让下次告警来的时候,值班的人能第一眼看到:这不是 JS 崩了,是 SVG 里写了 transition: all。 哦对,工牌上那块咖啡渍还没洗掉。昨天淋了雨,泡开了,现在看起来像一小片潮红的地图。 (编辑:站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |





