HTTP/2 和压缩可能减少资源传输,改善 LCP 等加载指标。但它们本身不能消除布局偏移,也不保证搜索排名提升。应分别检查传输、渲染和用户操作。
区分 HTTP/2 与 HTTPS
HTTP/2 在一个连接上多路复用请求,减少 HTTP 层面的阻塞。它仍使用 TCP,因此丢包可能延迟多个流。HTTP/3 已在使用,并采用不同的传输方式。应依据测量结果和托管环境支持情况选择。
浏览器通过 TLS 使用 HTTP/2。在 Vercel 等托管服务上,应检查实际协商的协议。自行托管时,可以由 Next.js 前面的反向代理或 CDN 处理 TLS 和 HTTP/2。单独使用 Node.js 的 https 模块并不会启用 HTTP/2。
下面的命令生成用于 localhost 本地 HTTPS 实验的证书,不适用于生产环境:
openssl req -x509 -newkey rsa:4096 -nodes -keyout key.pem -out cert.pem -days 365 -subj '/CN=localhost' -addext 'subjectAltName=DNS:localhost'
以下自定义服务器演示的是 HTTP/1.1 上的 HTTPS,并非 HTTP/2 部署。它需要已有的 Next.js 项目,生产模式还需要完成构建。通常应优先使用代理后面的标准 Next.js 服务器。
import next from 'next'
import fs from 'node:fs'
import https from 'node:https'
const app = next({ dev: process.env.NODE_ENV !== 'production', port: 3000 })
const handle = app.getRequestHandler()
async function startServer() {
await app.prepare()
https
.createServer(
{
cert: fs.readFileSync('./cert.pem'),
key: fs.readFileSync('./key.pem'),
},
async (request, response) => {
await handle(request, response)
},
)
.listen(3000)
console.info(`Ready on https://localhost:3000`)
}
startServer()
检查实际协议和压缩
在 Chrome DevTools 的 Network 中查看 Protocol 列。对于支持 HTTP/2 的 curl,第一个命令输出实际使用的协议版本;请求 HTTP/2 仍可能回退到其他版本。第二个命令声明支持 Brotli 和 gzip,并检查 GET 响应头。
curl --http2 -sS -o /dev/null -w '%{http_version}\n' https://your-site.com
curl -sS -D - -o /dev/null -H 'Accept-Encoding: br, gzip' https://your-site.com
Brotli 与 gzip
使用 next start 时,Next.js 默认采用 gzip。Brotli 可能产生更小的文本响应,但不存在统一的 20%~25% 节省比例。托管服务应检查实际响应;自行托管则在支持的代理或 CDN 上配置 Brotli。
只有在其他层已经承担压缩后,才应关闭 Next.js 压缩。以下设置本身并不启用 Brotli:
// next.config.mjs
export default {
compress: false,
}
Brotli 响应可能包含以下响应头:
Content-Encoding: br
Vary: Accept-Encoding
不要为未压缩的响应体手动设置 Content-Encoding。还应检查回退版本,以及缓存如何处理 Accept-Encoding。以下数值仅为说明性示例,不是实测或保证的压缩比:
| 格式 | 原始 JavaScript | 示例压缩大小 |
|---|---|---|
| Gzip | 100 KB | 30 KB |
| Brotli | 100 KB | 22 KB |
预取与 Server Push
Next.js 的 Link 可以预取路由资源。这是浏览器发起的请求,并非 HTTP/2 Server Push。Chrome 从 106 版本起默认禁用 Server Push,当前的优化方案不应依赖它。
import Link from 'next/link'
export default function AboutLink() {
return <Link href="/about" prefetch>About</Link>
}
对于确认关键的字体,可以考虑 preload。请将示例 URL 替换为实际资源,并匹配类型和 cross-origin 设置:
<link rel="preload" href="/fonts/site.woff2" as="font" type="font/woff2" crossorigin>
预取和预加载会消耗带宽。不存在五个或六个资源的统一上限,应以加载或导航的实际收益为依据。
图片优化
next/image 根据配置和浏览器的 Accept 选择优化格式。默认输出为 WebP;AVIF 需要相应配置。指定尺寸可以预留空间,减少布局偏移。
import Image from 'next/image'
export default function ExampleImage() {
return <Image src="/example.jpg" alt="Example" width={800} height={600} quality={75} />
}
下面的大小仅为示例,实际取决于图片、分辨率和质量。应检查受众使用的浏览器,而不是依赖固定支持率。
| 格式 | 1920 × 1080 示例 | 支持检查 |
|---|---|---|
| JPEG | 200 KB | 目标浏览器 |
| WebP | 120 KB | 目标浏览器 |
| AVIF | 80 KB | 目标浏览器 |
常见问题与比较
| 问题 | 检查内容 |
|---|---|
| 缺少有效 TLS 证书 | 通过 Let’s Encrypt 等配置受信任的生产证书。 |
| 预期的 Brotli 未返回 | 检查请求和响应头、内容类型及代理。 |
| 提前请求过多 | 删除无用的 prefetch/preload,重新测量。 |
在相同设备、网络和缓存条件下比较同一页面。Speed Scanner 和 WebPageTest 可以辅助分析,但协议名称本身不能证明改进。请保存配置和结果。

