跳转到文章
Performance2026年10月20日阅读约 2 分钟

Next.js 中的 HTTP/2 与 Brotli:配置和验证

检查 Next.js 的协议和响应压缩,区分 HTTPS 与 HTTP/2、预取与 Server Push,并测量实际效果。

Next.js 中的 HTTP/2 与 Brotli:配置和验证

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示例压缩大小
Gzip100 KB30 KB
Brotli100 KB22 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 示例支持检查
JPEG200 KB目标浏览器
WebP120 KB目标浏览器
AVIF80 KB目标浏览器

常见问题与比较

问题检查内容
缺少有效 TLS 证书通过 Let’s Encrypt 等配置受信任的生产证书。
预期的 Brotli 未返回检查请求和响应头、内容类型及代理。
提前请求过多删除无用的 prefetch/preload,重新测量。

在相同设备、网络和缓存条件下比较同一页面。Speed Scanner 和 WebPageTest 可以辅助分析,但协议名称本身不能证明改进。请保存配置和结果。

网站速度检测

找出拖慢网站速度的原因

使用 Milten 检测页面,查看 Core Web Vitals 指标并获取加快加载速度的建议。

检测网站
Cookies

我们使用 Cookie

我们使用 Cookie 以在你的网站上为你提供更好的体验。你可以在我们的 隐私政策.