性能优化最容易犯的错是先改代码再看效果。正确顺序是:先量出 LCP、CLS、INP,再针对最大的那项动手。多数内容站点的瓶颈在图片与字体,而不是框架。

前端性能优化清单:图片、字体与关键渲染路径 示意图

先量化

Chrome DevTools 的 Performance 面板能看主线程与渲染时间,Lighthouse 给出评分与建议。线上更推荐用 PerformanceObserver 采集真实用户数据:

new PerformanceObserver((list) => {
    for (const entry of list.getEntries()) {
        // 上报最大的内容绘制时间
        report('lcp', entry.startTime);
    }
}).observe({ type: 'largest-contentful-paint', buffered: true });

没有真实数据的优化都是猜。先确认是「首屏图太大」还是「字体阻塞」,再决定改哪里。

图片:格式、尺寸与优先级

  • 照片用 WebP 或 AVIF,体积通常比 JPEG 小 25%~50%;
  • 按实际展示尺寸输出,不要用 3000px 原图缩到 300px;
  • 首屏图加 fetchpriority="high",折叠以下的图加 loading="lazy";
  • 给图片写死 width / height 或 aspect-ratio,避免加载后跳版。
<img src="/img/cover.webp" alt="封面"
     width="1200" height="630"
     fetchpriority="high" decoding="async">

需要批量转换格式或压缩时,用站内的图片处理工具可以一次完成压缩、裁剪与转 WebP,不必为几张图单独装环境。

字体:别让文字等字体

@font-face {
    font-family: "Site Sans";
    src: url("/fonts/site-sans.woff2") format("woff2");
    font-display: swap;
    unicode-range: U+4E00-9FFF;
}
  • 用 woff2,不要同时加载多个格式;
  • font-display: swap 让文字先用系统字体显示,避免白屏;
  • 中文字体体积大,做子集化(只保留常用字)或直接使用系统字体;
  • 关键字体可 preload,但只限一个文件,多了反而抢占带宽。

关键渲染路径

浏览器要先拿到 HTML、解析出 CSS,才能绘制首屏。阻塞渲染的资源越少,首屏越快。

  • 首屏必需的 CSS 内联到 head,其余样式异步加载;
  • 脚本加 defer,不要放在 head 里同步执行;
  • 减少第三方脚本,统计与客服组件的加载时机放到首屏之后;
  • 用 preconnect 提前建立关键域名连接,例如字体或 CDN 域名。

布局稳定性(CLS)

图片没写尺寸、广告位动态插入、字体切换导致行高变化,都会让内容「跳一下」。做法很直接:给所有媒体元素预留空间,动态内容用固定高度的占位容器。

.media {
    aspect-ratio: 16 / 9;
    background: #f1f5f9;
}

一份可执行的检查清单

  • 首屏最大的图是否已压缩并转 WebP;
  • 是否只加载了首屏需要的字体与图标;
  • JS 是否都用了 defer 或 type="module";
  • 图片、iframe 是否都有尺寸或占位;
  • 是否清理了未使用的 CSS 与依赖;
  • 是否在 4G 网络下实测过一次首屏。

小结

性能优化是「测量 → 改一项 → 再测量」的循环,不是一次性把所有手段堆上去。内容站点优先解决图片与字体,通常就能拿到大部分收益。布局层面的调整可以参考Grid 与 Flexbox 的选型,两者一起看,页面会又快又稳。