你的网站加载慢,可能真不是服务器的锅
你有没有试过:图片压缩了、CDN开了、服务器升级了,首页还是卡在2秒多?打开 Chrome 的 Network 面板一看——所有请求排着队,像早高峰地铁进站一样等那6个连接轮流转。别折腾了,问题大概率出在协议上:你还在用 HTTP/1.1。
HTTP/2到底改了什么?为什么能快这么多?
HTTP/1.1 的底层逻辑很“老实”:一个请求配一个 TCP 连接。浏览器怕压垮服务器,硬性限制每个域名最多开6个连接。你页面里有30个资源?那就得排队、拆成5批,一批接一批地等。
更烦的是,每次请求都得重复发一整套头部信息——Cookie、User-Agent、Accept-Encoding……全是明文,动不动几百字节。这些内容几乎一模一样,却次次重传。
HTTP/2 换了一种思路:
- 用「多路复用」把几十个请求塞进同一个连接里,谁的数据先准备好,谁就先发回来,不用等前面的。
- 用「HPACK 头部压缩」把重复字段换成短索引,比如
:method: GET变成一个数字2,头部体积直接砍掉一大截。
我之前调过一个企业官网,没动代码、没换图,只启用了 HTTP/2。再看瀑布图:原来拉成一条长线的请求,突然变成十几条并排的短条——所有 CSS、JS、字体几乎同时开始下载。
至于 HTTP/3?它确实更进一步,用 QUIC 绕开了 TCP 的队头阻塞,但落地太慢:很多 CDN 还不支持,Nginx 要编译新模块,连部分安卓 WebView 都认不出。对绝大多数人来说,HTTP/2 是现在最稳、最快、最省事的提速入口。
怎么判断你的网站现在用的什么协议?
打开 Chrome,按 F12 → 切到 Network → 刷新页面 → 点任意一个请求 → 往下拉到 Headers → 找 Request Headers 区域里的 :scheme 或 Protocol 字段。
看到 http/1.1?老协议。
看到 h2 或 http/2?已经跑起来了。
真实情况比想象中“玄学”:
- 有个朋友的电商站,Nginx 配置文件里明明写了
http2,结果全是 HTTP/1.1。查了半天,发现是编译 Nginx 时漏掉了--with-http_v2_module,重新编译才解决。 - 另一个用 Cloudflare 的博客,默认走 HTTP/2,但后台关了 Server Push,关键 CSS 总要等 HTML 解析完才发起请求,首屏渲染卡了一下。打开 Push 后,那一下“卡顿感”就没了。
如果你用的是主流 CDN(Cloudflare / Fastly / Akamai),基本默认就开着 HTTP/2,进控制台确认下开关就行。
自建服务器的话:
- Nginx:检查
listen 443 ssl;这行有没有加上http2; - Apache:确保启用了
mod_http2,并在<VirtualHost>里加一句Protocols h2 h2c http/1.1。
开启HTTP/2之前,必须先检查这3个坑
第一,HTTPS 是硬门槛。
所有主流浏览器(Chrome、Firefox、Edge、Safari)只认加密的 HTTP/2。也就是说,http:// 网站永远用不上它。好消息是:Let’s Encrypt 的免费证书现在一键就能装,acme.sh 或 Certbot 都能自动续期,不用花钱,也不用折腾。
第二,服务器版本不能太老。
Nginx 必须 ≥ 1.9.5,Apache 必须 ≥ 2.4.17。我见过一台跑着 Nginx 1.8 的老服务器,升级到 1.20 后,http2 参数才真正生效。用 cPanel 或 Plesk 的同学,面板里通常有开关,但如果点不动或报错,大概率是底层版本太低,得先升级。
第三,小心“半吊子”启用。
主站开了 HTTP/2,但图片从 img.example.com 加载,而这个子域名还在跑 HTTP/1.1?那等于白开——浏览器会为这个子域名单独开6个连接排队。最好把静态资源统一收口到主域名下,或者全交给 CDN 处理。我们之前优化一个媒体站,主站飞快,但第三方统计脚本和 Google Fonts 仍是 HTTP/1.1,整体加载时间根本没下来。
开启后,这2个配置能让速度再翻倍
Server Push 不是越多越好。
它的作用是在返回 HTML 的同时,主动把首屏必需的 CSS、JS 推送给浏览器,省掉一次 RTT。但推错了反而拖后腿:比如把整站 JS 都推过去,带宽被占满,HTML 都卡住。我的做法很保守:首页只推 main.css 和 critical.js,其他资源留给浏览器按需取。开启后,LCP(最大内容绘制)时间明显提前。
并发流数别卡太死。
HTTP/2 默认允许一个连接处理 100 个并发请求,够用。但有些 CDN 或旧版 Nginx 把 http2_max_concurrent_streams 设成 16 或 32,成了隐形瓶颈。建议调到 128。我们调过一个社区论坛,把这值从默认 16 改成 128,用户上传图片后预览加载快了一大截。
另外,头部压缩在 HTTP/2 中是默认开启的,但如果你用的是 Nginx 1.10 之前的版本,可能需要手动加一行 http2_header_compression on;。开了之后,每个请求的头部从几百字节缩到几十字节——积少成多,对移动端尤其友好。
一个真实案例:从3秒到0.8秒,只改了一个参数
去年帮一个旅游攻略站做诊断。页面堆了七八个地图插件、二十多张高清图、三四套字体,HTTP/1.1 下瀑布图像一条蜈蚣:第一个请求等了1秒多才发出,后面全在排队,总耗时 3 秒出头。
改法极其简单:SSH 登服务器,找到 Nginx 站点配置,在 listen 443 ssl; 后面加上 http2,保存,nginx -t 测试,systemctl reload nginx。
再刷一次页面:所有资源几乎同时出发,TTFB 缩短,LCP 提前,总加载时间掉到 0.8 秒左右。站长自己刷新了三遍,说:“这不像优化,像开了挂。”
但这里有个反直觉的细节:HTTP/2 让“减少请求数”这条老规矩失效了。以前拼命合并 CSS、拼雪碧图,是为了绕过 HTTP/1.1 的连接限制;现在多路复用让 10 个小文件并行加载,比 1 个大文件还快。我们顺手把合并的 all.css 拆回 base.css theme.css map.css print.css 四个文件,把雪碧图也还原成单图,结果加载又快了小一圈。
今天就能做的3个操作步骤
第一步:打开 Chrome,按 F12 → Network → 刷新页面 → 点一个请求 → 看 Protocol 字段。如果是 http/1.1,继续。
第二步:
- 如果你用 Nginx:SSH 登录服务器,编辑
/etc/nginx/sites-enabled/your-site.conf,把listen 443 ssl;改成listen 443 ssl http2;,然后执行:nginx -t && systemctl reload nginx - 如果你用 Apache:编辑虚拟主机配置,在
<VirtualHost>块里加上:然后运行:Protocols h2 h2c http/1.1sudo a2enmod http2 && systemctl restart apache2 - 如果你用 Cloudflare:登录后台 → Speed → Optimization → 找到「HTTP/2」开关,确保是 ON。
第三步:改完立刻验证。再打开 Chrome Network 面板,看 Protocol 是否变成 h2;同时用浏览器自带的 Lighthouse(右键 → “检查” → Lighthouse 标签页)跑一次测试,重点关注「First Contentful Paint」和「Largest Contentful Paint」有没有缩短。如果某些资源变慢了,重点查它们的域名是否还走 HTTP/1.1——尤其是第三方脚本、字体、广告位。