性能优化最怕"感觉慢了"但没有依据。先把指标定义清楚,再按投入产出比从高到低逐项落地, 是效率最高的做法。这篇文章整理了一份我常用的清单,从"怎么量"到"怎么改"。

先看三个核心指标

  • LCP(Largest Contentful Paint):首屏最大内容元素的渲染时间,衡量"页面看起来加载完了", 目标 < 2.5s;
  • CLS(Cumulative Layout Shift):布局偏移累计分,衡量页面元素是否"跳动", 目标 < 0.1;
  • INP(Interaction to Next Paint):交互响应延迟,衡量点击后界面多快给出反馈,目标 < 200ms。

这三个指标对应了用户体验的三个方面:加载快不快、稳不稳、跟不跟手。 用 Lighthouse 或 Chrome DevTools 的 Performance 面板可以很方便地测量。

图片:首屏优化的最大杠杆

图片往往占据页面传输体积的大头,优先级最高:

  • 格式升级:用 WebP / AVIF 替代 JPEG / PNG,同等画质体积可减小 30%–70%;
  • 尺寸匹配:不要用 2000px 的图展示 400px 的缩略图,按实际展示尺寸输出;
  • 懒加载:视口外的图片加 loading="lazy",首屏只加载真正可见的;
  • 预留空间:给图片容器设置宽高比(aspect-ratio),避免加载后把页面"顶开",这是 CLS 的常见来源。
<img src="hero.webp"
     width="1200" height="675"
     fetchpriority="high"
     alt="首屏大图">

<img src="thumb.webp"
     width="400" height="300"
     loading="lazy"
     decoding="async"
     alt="懒加载缩略图">

字体:别让文字"隐形"

自定义字体加载期间,浏览器可能不渲染文字(FOIT,Flash of Invisible Text), 直接拉高 LCP。优化手段:

  • font-display: swap,先显示系统字体,字体就绪后再切换;
  • unicode-range 做字体子集化,中文站只加载用到的字符;
  • preload 提前加载关键字体文件。

脚本与 CSS:减少主线程占用

  • 脚本加 defer:不阻塞 HTML 解析,在 DOM 就绪后按顺序执行; async 只适合完全独立的脚本(如统计代码);
  • 代码分割:路由级懒加载,首屏只下载当前页面需要的 JS 块(Code Splitting);
  • 关键 CSS 内联:首屏样式直接内联在 <head>,外部样式表用 media 或异步加载,避免阻塞渲染;
  • preconnect 与 dns-prefetch:提前建立与第三方域名(CDN、字体站)的连接:
<link rel="preconnect" href="https://cdn.example.com" crossorigin>
<link rel="dns-prefetch" href="https://api.example.com">
<link rel="preload" href="font.woff2" as="font" type="font/woff2" crossorigin>

一个容易忽略的点:服务器响应时间

前端优化做得再好,TTFB(首字节时间)超过 1s 也无济于事。检查: 静态资源是否走了 CDN、是否有缓存(配合上篇的缓存策略)、服务端有没有慢查询或未压缩 (确保开启 gzip / brotli)。

落地顺序建议

  1. 先测一遍 Lighthouse,记下三个指标的基线值;
  2. 图片格式 + 尺寸 + 懒加载(收益最大,改动最小);
  3. 字体 swap + 子集化;
  4. 脚本 defer + 代码分割;
  5. CDN + 缓存 + 压缩(如果还没有);
  6. 再测一遍,对比基线,把数值写进文档,防止回退。

总结:先量化,再动手。图片是杠杆,字体别隐形,脚本别阻塞,服务器别拖后腿——按这个顺序做,首屏体验的提升是肉眼可见的。