把首屏从 3 秒压到 1 秒以内,绝大多数收益来自三件事:缓存、压缩、少发请求。这篇按收益从高到低排列。
第一优先:让静态资源带上长缓存
浏览器每次访问都要判断资源是否过期,这个往返本身就是成本。给静态资源加一年缓存,并用文件名指纹来失效:
location ~* \.(css|js|png|jpg|jpeg|gif|svg|webp|woff2)$ {
expires 1y;
add_header Cache-Control "public, immutable";
access_log off;
}immutable 告诉浏览器「这个文件在有效期内绝对不会变」,连条件请求都省了。
配套要求:文件内容变了,文件名必须变。常见做法是加 hash,例如 style.a1b2c3.css。
第二:开启压缩
gzip on;
gzip_comp_level 5; # 6 以上收益很小但 CPU 明显上升
gzip_min_length 1024; # 太小的文件压缩不划算
gzip_types text/plain text/css application/javascript application/json
image/svg+xml application/xml;
# 预压缩的文件优先直接发送
gzip_static on;
# 新版本浏览器优先用 brotli(需编译模块)
# brotli on;
# brotli_comp_level 5;
# brotli_types text/css application/javascript application/json image/svg+xml;HTML 一般能压到 20% 左右,CSS/JS 能到 25%。这是纯收益,只要注意别把 gzip_comp_level 调太高。
第三:减少请求数与体积
- 图片:统一转 WebP,通常比 JPEG 小 25%–35%。
<img>上加loading="lazy"(首屏图片除外)和width/height避免布局抖动。 - 字体:优先用系统字体,或只加载用到的字重。中文字体整包动辄几 MB,务必做子集化。
- 关键 CSS:把首屏样式内联进
<head>,其余异步加载,可显著改善首次渲染时间。
<link rel="preload" href="/style.css" as="style" onload="this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="/style.css"></noscript>验证方法
不要凭感觉。用命令行确认压缩与缓存是否真的生效:
curl -sI -H 'Accept-Encoding: gzip' https://it365.wang/ | grep -Ei 'content-encoding|cache-control'期望输出里同时出现 content-encoding: gzip 和 cache-control: public, ...。如果没有,说明配置没匹配上——优先检查 gzip_types 是否漏了你实际用的 MIME 类型。
小结
顺序:长缓存 → 压缩 → 减少请求。前两步是配置改动,收益最大;第三步涉及前端资源组织,收益次之但更持久。做完用 curl -sI 逐项验证,别停在「应该生效了」。