前端性能优化:先测量,再优化

作者:三分钟热度 发布时间: 2026-06-13 阅读量:88 评论数:0

先说结论:我见过的前端性能优化里,至少有一半的力气花在了用户根本感知不到的地方。包括我自己。

那两天我省错了地方

三年前我接手一个后台管理系统,第一天打开就觉得慢。我当时的反应特别典型——立刻打开构建配置,开始琢磨怎么拆包、怎么按需引入、要不要把静态资源挪到边缘节点。折腾了两天,产物体积从 2.8MB 降到 2.1MB,我心满意足地写进了周报。结果测试同事回了一句:还是差不多慢啊。

后来我老老实实打开性能面板录了一段。录完就傻眼了:从导航开始到首屏可交互一共 4.2 秒,其中脚本下载和解析加起来只占 900 毫秒左右,真正的大头是一段 2.6 秒的空白——页面挂载后串行发了三个请求,第一个拿当前用户,第二个用用户信息拿组织树,第三个才拿列表数据。每个请求 800 毫秒上下,串起来就是两秒半。

我优化掉的那 700KB,在用户的宽带上大概能省 200 毫秒。而我花两天做的事,抵不上把三个串行请求改成两个并行加一个后置——那是十几行代码的事。

我现在的测量顺序

  • 先看最大内容渲染落在哪个元素上。很多时候你以为的首屏主体,浏览器根本不认,它标的是一张背景图或者一段骨架占位。这一步经常直接推翻我的直觉。
  • 再看主线程的长任务。超过 50 毫秒的任务展开火焰图看调用栈,一般能直接指到某个同步计算或者某个组件的初始化逻辑。
  • 然后看瀑布图里的空白段。空白意味着在等:等网络、等上一个响应、等某个没必要的 await。空白比忙碌更值得关注,因为忙碌至少还在干活。
  • 最后才看体积。

两个具体的坑

有一次列表页滚动卡顿,火焰图指向一个日期格式化函数,它在一次渲染里被调用了将近三万次——每行每列都调用一次,而函数内部每次都新建一个格式化器实例。把实例提到模块顶层复用,单次渲染从 480 毫秒掉到 60 毫秒。改动两行,比我拆包两天有用得多。

还有一次是字体。设计稿要求一套字体四种字重,每种一个文件,共 380KB,而且没设置 font-display,于是文字在字体加载完成前完全不可见。用户看到的是一片空白,但自动化评分工具给的分数并不难看,因为它统计的是最终渲染完成的时刻。这种问题只能靠自己在真机上限速跑一遍才能发现。

给自己定的两条规矩

第一,任何优化必须先有一个数字,改完必须有第二个数字。哪怕这个数字是我在同一台机器、同样的限速条件下手动录三次取中位数,也比拍脑袋强。我现在会把优化前后的录制文件存下来,文件名带日期,回头能对着看。

第二,优先做用户能感知的事。骨架屏不会让页面快一毫秒,但它能把两秒的等待从焦虑变成可接受。反过来,把 60 毫秒的操作优化到 30 毫秒,没有任何人会发现。人的感知是分档的:100 毫秒内像即时反馈,1 秒内还算流畅,超过 3 秒就开始怀疑是不是坏了。优化要跨档才有意义。

说来惭愧,这两条规矩是我用两天无用功买回来的。

评论