“上HTTPS会不会影响性能?”——这个问题从2014年Google全站HTTPS化到现在,被问了十几年。到2026年,答案是:不优化的话确实会慢一点,但优化得当,HTTPS甚至可能比HTTP更快。这篇文章把TLS握手的原理拆给你看,再给5个实战优化手段,读完你的网站评分和速度都能拉满。

先给结论:HTTPS比HTTP多了什么开销?

不绕弯子,直接说清楚HTTPS比HTTP多出的性能成本:

  1. 连接建立阶段:多了1-2个RTT(往返时间)的TLS握手
  2. 数据传输阶段:加密解密的CPU计算开销
  3. 证书验证阶段:浏览器验证证书链和吊销状态的网络请求

这三项加起来,未优化的HTTPS首次连接可能比HTTP慢200-400毫秒。后续请求如果复用连接,差距会缩小到几乎可忽略。

200-400毫秒多不多?对于追求极致性能的场景(比如搜索页面、信息流首屏),是有感知的。对于大多数企业官网、管理后台、内容站——用户根本感觉不到。

但"感觉不到"不等于"不用优化"。下面逐项拆解原理,然后给实战方案。


原理篇:TLS握手到底在干什么?

要理解HTTPS的性能开销,先搞清楚TLS握手的过程。以目前最主流的TLS 1.2为例:

TLS 1.2握手流程

客户端                                     服务端
  |                                          |
  | --- 1. ClientHello ----------------------> |
  |     (支持的TLS版本、加密套件、随机数)       |
  |                                          |
  | <--- 2. ServerHello --------------------- |
  |     (选定TLS版本、加密套件、随机数)         |
  | <--- 3. Certificate --------------------- |
  |     (服务端证书)                           |
  | <--- 4. ServerHelloDone ----------------- |
  |                                          |
  | --- 5. ClientKeyExchange ----------------> |
  |     (生成Pre-Master Secret,用服务端公钥加密)|
  | --- 6. ChangeCipherSpec -----------------> |
  | --- 7. Finished -------------------------> |
  |                                          |
  | <--- 8. ChangeCipherSpec ----------------- |
  | <--- 9. Finished ------------------------ |
  |                                          |
  | ===== 10. 加密数据传输 ================== |

数一下箭头:2个RTT完成握手,第3个RTT才开始传应用数据。

对比HTTP(TCP握手1个RTT + 直接传数据),TLS 1.2多了整整2个RTT的握手时间。

TLS 1.3握手流程

TLS 1.3把这个过程压缩了:

客户端                                     服务端
  |                                          |
  | --- 1. ClientHello ----------------------> |
  |     (含密钥交换参数,一步到位)              |
  |                                          |
  | <--- 2. ServerHello --------------------- |
  |     (含密钥交换参数 + 证书 + Finished)      |
  |                                          |
  | --- 3. Finished -------------------------> |
  |                                          |
  | ===== 4. 加密数据传输 =================== |

1个RTT完成握手,第2个RTT就开始传数据。比TLS 1.2快了一倍。

0-RTT模式

TLS 1.3还支持0-RTT(Early Data)——如果客户端之前跟这个服务端建立过连接,可以在第一个数据包里直接带上应用数据。相当于零额外往返,和HTTP一样快

不过0-RTT有重放攻击的风险,只适合幂等的GET请求。实际部署中通常选择性开启。


优化手段一:升级到TLS 1.3

这是收益最大、成本最低的优化。

效果:握手从2-RTT降到1-RTT,首字节时间(TTFB)减少约1个RTT。

配置方法(Nginx)

ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers TLS13-AES128-GCM-SHA256:TLS13-CHACHA20-POLY1305-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;

注意事项

  • TLS 1.3需要OpenSSL 1.1.1及以上版本,Nginx 1.13.0及以上版本
  • 保留TLS 1.2作为兼容——少数老旧客户端(Android 4.x等)不支持1.3
  • TLS 1.3的Cipher Suite名称以 TLS13- 开头,和1.2的不能混用

收益预估:如果你的用户主要在国内,移动端RTT通常在50-150ms,升级到TLS 1.3直接省掉一个RTT,首屏体验有实际提升。


优化手段二:开启Session Resumption

TLS握手慢是因为每次都要重新协商密钥。但如果客户端"刚连过",可以跳过大部分握手步骤。

两种实现方式

方式A:Session ID(传统方式)

服务端在握手时给客户端发一个Session ID,客户端下次连接时带上这个ID,服务端认出来了,直接复用之前的密钥参数,握手缩短到1-RTT(TLS 1.2)。

ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
  • shared:SSL:10m:在所有worker进程间共享一个10MB的缓存,大约能存4万个session
  • ssl_session_timeout 1d:session有效期1天

方式B:Session Ticket(更灵活)

服务端把session信息加密后发给客户端,客户端自己存着,下次连接时带给服务端。服务端不需要在内存里维护session状态,更适合多服务器负载均衡场景。

ssl_session_tickets on;
ssl_session_ticket_key /etc/nginx/ssl/ticket.key;

注意事项:多台服务器要共享同一个 ticket.key 文件,否则A机器发的ticket到B机器验证不过。

收益预估:对回访用户,握手时间减少约50%。内容站、SaaS这类用户高频回访的场景收益最明显。


优化手段三:开启OCSP Stapling

这个优化解决的是一个隐蔽但影响很大的问题。

问题是什么?

浏览器验证证书时,需要检查证书是否被吊销。两种检查方式:

  • CRL(证书吊销列表):浏览器下载一份完整吊销列表,文件大、更新慢,基本被淘汰
  • OCSP(在线证书状态协议):浏览器向CA的OCSP服务器发请求,实时查这张证书是否有效

问题在于:浏览器发OCSP请求时,要连到CA的服务器。如果CA的OCSP服务器响应慢(有的在海外),或者网络不通,浏览器会等待几百毫秒甚至超时。这就是很多HTTPS站点"感觉慢"的隐藏元凶。

更糟糕的是,这个请求还泄露了用户隐私——CA知道你访问了哪个网站。

OCSP Stapling怎么解决

服务端定期自己去查OCSP状态,把结果"钉"(Staple)在握手时发给浏览器。浏览器不用自己去查了,握手速度更快,隐私也不泄露。

ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/nginx/ssl/ca-bundle.crt;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;

注意事项

  • 必须配置 ssl_trusted_certificate(含完整证书链),否则stapling验证会失败
  • 需要配置DNS resolver,因为Nginx要解析OCSP服务器的域名
  • 配置完后用 openssl s_client -connect example.com:443 -status 验证,看到 OCSP Response Status: successful 就说明生效了

收益预估:取决于你的CA的OCSP服务器位置。如果CA在海外,国内用户访问OCSP可能要200-500ms。开启Stapling后这部分延迟直接消失。


优化手段四:启用HTTP/2

HTTP/2不是SSL优化,但它和HTTPS强绑定——所有主流浏览器只在HTTPS连接上启用HTTP/2。

HTTP/2为什么能让HTTPS更快

HTTP/1.1的问题:一个TCP连接同时只能处理一个请求。你要加载HTML + CSS + JS + 图片,要么排队等,要么开多个TCP连接(每个连接又要单独握手)。

HTTP/2的解决方案:多路复用。一个TCP连接上可以同时跑无数个请求,互不阻塞。

对于HTTPS来说,这意味着——你只需要做一次TLS握手,就能在这个连接上并行加载所有资源。TLS握手的成本被"摊薄"到了所有请求上。

listen 443 ssl http2;
# Nginx 1.25.1+ 的新语法
# listen 443 ssl;
# http2 on;

额外建议

  • 配合Server Push(服务端主动推送关键资源)可以进一步减少首屏往返
  • 开启HTTP/2后,合并CSS/JS文件的收益降低(因为多路复用不再有队头阻塞),反而保持小文件独立加载更利于缓存

收益预估:页面资源越多,收益越大。一个加载20个资源的页面,HTTP/2比HTTP/1.1 over TLS快30%-50%。


优化手段五:精简证书链

证书链太长,握手时传输的数据量就大,首字节时间拉长。

什么是证书链过长

你的证书 → 中间CA证书 → 根CA证书。有些CA签发证书时会套2-3层中间证书,每多一层,握手时多传1-2KB数据。

更常见的问题是:把根证书也放进了证书链文件里。根证书已经预置在浏览器/操作系统中,不需要在握手时传过去。传了就是浪费带宽。

怎么精简

检查你的证书链文件,只保留必要的中间证书,去掉根证书:

# 查看证书链包含几层
openssl s_client -connect example.com:443 -showcerts 2>/dev/null \
  | grep -c "BEGIN CERTIFICATE"

如果返回3以上,大概率包含了多余的证书。手动检查每一层,只保留从你的网站证书到中间证书的部分,去掉根CA。

正确做法:把你的证书和中间CA证书合并成一个文件:

cat your_cert.crt intermediate.crt > fullchain.crt

然后在Nginx中配置:

ssl_certificate /etc/nginx/ssl/fullchain.crt;

收益预估:精简证书链后握手数据量减少1-3KB,在弱网环境下(移动端3G/4G)可减少50-100ms传输时间。


把所有优化拼在一起:完整的Nginx配置参考

server {
    listen 443 ssl http2;
    server_name example.com;

    # 证书
    ssl_certificate     /etc/nginx/ssl/fullchain.crt;
    ssl_certificate_key /etc/nginx/ssl/example.com.key;

    # TLS 1.2 + 1.3
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers TLS13-AES128-GCM-SHA256:TLS13-CHACHA20-POLY1305-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
    ssl_prefer_server_ciphers on;

    # Session Resumption
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 1d;
    ssl_session_tickets on;
    ssl_session_ticket_key /etc/nginx/ssl/ticket.key;

    # OCSP Stapling
    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_trusted_certificate /etc/nginx/ssl/ca-bundle.crt;
    resolver 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 5s;

    # HSTS
    add_header Strict-Transport-Security "max-age=63072000" always;

    # 其他配置...
    root /var/www/html;
    index index.html;
}

用SSL Labs跑一遍,这套配置应该能拿到A甚至A+。


实测数据:优化前后对比

以下是典型的优化前后对比(国内服务器 + 移动4G网络环境):

指标 未优化HTTPS 优化后HTTPS 提升幅度
首次连接握手耗时 ~350ms ~120ms 65%↓
回访连接握手耗时 ~350ms ~40ms 88%↓
证书验证等待 ~200ms 0ms(Stapling) 100%↓
首屏完整加载(20资源) ~2.8s ~1.9s 32%↓
SSL Labs评分 B A+

注:数据为典型场景参考值,实际效果取决于服务器配置、网络环境和用户设备。

可以看到,优化后的HTTPS在回访场景下握手只要40ms,和HTTP的TCP握手(约30-40ms)几乎没有差别。这就是"优化得当,HTTPS不比HTTP慢"的依据。


最后说句大实话

很多人把"HTTPS慢"当作不上HTTPS的借口。到2026年,这个借口已经站不住了:

  • TLS 1.3已经把握手压缩到1-RTT,0-RTT甚至能零额外开销
  • HTTP/2的多路复用让HTTPS反而比HTTP/1.1更快(并行加载)
  • 现代CPU的AES-NI指令集让加密解密开销降到每请求微秒级
  • 主流CDN全部支持HTTPS加速,边缘节点帮你做TLS终结

你唯一需要做的,就是把上面5个优化项配好。配完之后,你的HTTPS网站不仅安全,而且快。


本文配置方案适用于Nginx 1.18+和OpenSSL 1.1.1+环境。Apache、Caddy等Web服务器的优化思路相同,具体指令请参考对应文档。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐