慢一秒流失一批用户,把网页做快是设计师和前端共同的活。
性能这件事,最容易被认为是“前端的事,和设计无关”。但只要做过一次性能优化的项目就会发现:一半的性能问题,根子在设计阶段就埋下了——首屏堆了太多大图,动效太多太重,字体加载了四五套。性能是设计决策的直接后果,设计师不参与,优化永远在补救。
性能和转化的关系有大量数据支撑。一个常被引用的结论是:页面加载每慢一秒,转化率约下降 7%。这数字不一定每个项目都准,但方向是对的——慢就是流失,尤其在移动端。用户没耐心等你慢慢展现你的精美设计,他直接关了。
首屏(用户第一眼看到的内容)能多快出来,决定了他会不会等下去。优化的核心是减少阻塞渲染的资源:CSS 默认阻塞渲染,JS 默认阻塞解析,字体加载会卡住文字显示。
三招立竿见影:关键 CSS 内联进 head,非关键 CSS 异步加载;JS 加 defer 或 async,放 body 末尾;字体用 font-display: swap,先用系统字体顶上,加载完再换。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<!-- 关键 CSS 内联,首屏立刻有样式 -->
<style>
body { margin: 0; font-family: system-ui, sans-serif; }
.hero { padding: 40px 20px; }
</style>
<!-- 非关键 CSS 异步加载 -->
<link rel="preload" href="css/main.css" as="style" onload="this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="css/main.css"></noscript>
</head>
<body>
<div class="hero">首屏内容</div>
<!-- JS 用 defer,不阻塞解析 -->
<script src="js/main.js" defer></script>
</body>
</html>
图片往往是页面里最大的体积来源,优化收益最高。三件事一起做:格式用 WebP(同质量比 JPG 小 25–35%),尺寸用 srcset 按屏幕给合适的图(小屏别下载大图),首屏外的图懒加载。
<picture>
<!-- 优先 WebP,不支持时回退 JPG -->
<source type="image/webp" srcset="img/hero-s.webp 480w, img/hero-m.webp 960w, img/hero-l.webp 1920w" sizes="100vw">
<source type="image/jpeg" srcset="img/hero-s.jpg 480w, img/hero-m.jpg 960w, img/hero-l.jpg 1920w" sizes="100vw">
<img src="img/hero-m.jpg" alt="首屏图" width="1920" height="800" fetchpriority="high">
</picture>
<!-- 首屏外的图:懒加载 + 给尺寸防布局抖动 -->
<img src="img/content.jpg" alt="内容图" loading="lazy" width="800" height="600">
给 width 和 height 很关键,浏览器会按比例预留位置,图片加载完不会把后面的内容顶下去(这正是 CLS 的主要来源)。首屏主图可以加 fetchpriority="high" 提前下载。
Google 用 Core Web Vitals 衡量页面体验,也是搜索排名的参考因素。三个指标记一下及格线:
CLS 是设计师能直接影响的:图片不给尺寸会跳,字体加载替换会跳,动态插入的内容会把现有内容顶下去。把尺寸定死、给字体留 fallback、避免在已有内容上方插入,CLS 自然就低。
性能不是一次性优化完就万事大吉,它会随着内容增加、功能迭代慢慢退化。需要持续监控两种数据:实验室数据(Lighthouse 定期跑,环境一致便于对比)和真实用户数据(RUM,收集真实用户的访问表现)。
// 简单的真实用户性能采集:上报 LCP
new PerformanceObserver((entryList) => {
const entries = entryList.getEntries();
const lcp = entries[entries.length - 1].startTime;
// 上报到自己的统计服务
navigator.sendBeacon('/stats', JSON.stringify({ metric: 'LCP', value: lcp }));
}).observe({ type: 'largest-contentful-paint', buffered: true });
实验室数据告诉你“理论上能多快”,真实用户数据告诉你“实际有多快”。两者经常差很多——你的电脑快、网络好,用户不一定。优化决策要参考真实用户数据,别只看 Lighthouse 跑分。
性能是隐形的设计。它不体现在设计稿里,但实实在在地影响每一个用户的感受。设计师和前端一起在项目早期就把性能当约束条件——图片体积、动效数量、字体套数、首屏内容量——比上线后再补救省力得多。记住一句话:能让用户在 1 秒里办完的事,别让他等 3 秒。