Nginx 优化静态资源加载 解决 Waiting(TTFB)时间过长问题

Nginx Apr 28, 2020 1

前因后果

我的MoMo导航网站每次加载都需要等待两三秒,一直以为是带宽问题(因为带宽真的小,钱的问题),后来开了全站 CDN 加速依然没有解决问题,今天正好没事就研究研究。

如图:多个静态文件 Waiting(TTFB) 时间过长

如图:Waiting(TTFB) 时间过长

都是静态资源,文件也不大,试了全站 CDN 和单个文件 CDN 没有任何效果,后来怀疑是Nginx 配置问题。经过查询文档检查配置最终找到问题。

解决办法第一步,启用缓存

Nginx 静态资源配置了禁用缓存,导致每次都重新加载。开启缓存后刷新就很快了,但是第一次加载依然是两三秒。

开启缓存静态资源

# 开启缓存,关闭静态资源日志记录,节省服务器资源
location ~ .*\.(gif|jpg|jpeg|png|ico|css|js|woff|woff2|ttf)$ {
    root	/usr/xxx;
    #禁用缓存
    #add_header Cache-Control no-cache; 
    # 关闭日志
    access_log off;
    #缓存7天
    expires 7d;		
}

解决办法第二步,启用 gzip 压缩

第一次加载依然是两三秒,解决办法是开启静态资源压缩,速度瞬间提升 20 倍哈哈。

http 模块加入以下配置

# 开启gzip
gzip  on;
# 启用gzip压缩的最小文件,小于设置值的文件将不会压缩
gzip_min_length 1k;
# gzip 压缩级别,1-10,数字越大压缩的越好,也越占用CPU时间。一般设置1和2
gzip_comp_level 1;
# 进行压缩的文件类型。javascript有多种形式。其中的值可以在 mime.types 文件中找到。
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
# 是否在http header中添加Vary: Accept-Encoding,建议开启
gzip_vary on;
# 禁用IE 8 gzip
gzip_disable "MSIE [1-8]\.";
# 设置缓存路径并且使用一块最大100M的共享内存,用于硬盘上的文件索引,包括文件名和请求次数,每个文件在1天内若不活跃(无请求)则从硬盘上淘汰,硬盘缓存最大10G,满了则根据LRU算法自动清除缓存。
proxy_cache_path /usr/local/nginx/cache/ levels=1:2 keys_zone=imgcache:100m inactive=1d max_size=10g;

再来看看现在,静态资源加载的速度,保持在100ms以内

解决办法第三步,启用 http2 协议(可选)

HTTP/2(超文本传输协议第2版,最初命名为HTTP 2.0),简称为h2(基于TLS/1.2或以上版本的加密连接)或h2c(非加密连接),是HTTP协议的的第二个主要版本,使用于万维网

如果没有安装http_v2_module模块,则需要重新编译安装。

./configure --user=nginx --group=nginx --prefix=/usr/local/nginx/ --with-http_addition_module --with-http_flv_module --with-http_gzip_static_module --with-http_realip_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_dav_module --with-http_v2_module --with-http_geoip_module --with-stream --with-stream=dynamic

Nginx 启用http2并优化https性能, 从而获得更好的 TTFB 和减少的延迟。

server {
    listen 443 ssl;
    # 改为
    listen 443 ssl http2;
    
    # https 优化
    # 减少SSL缓冲区大小,默认情况下,缓冲区为16k,这是一种“一刀切”的方法,旨在应对较大的响应。但是,为了最大程度地减少TTFB,通常最好使用较小的值。
    ssl_buffer_size 4k;
    ssl_prefer_server_ciphers on;
    ssl_protocols TLSv1.2 TLSv1.3; # 最低支持1.2 协议配置
    # 使用http2并启用Nginx ssl_session_cache将确保初始连接的HTTPS性能更快,并且页面加载速度快于http。
    ssl_session_cache shared:SSL:1m; # 可容纳约4000个会话
    ssl_session_timeout 24h; # 24小时,在此期间可以重复使用会话
    # 由于Nginx尚未正确实现会话票证加密密钥的轮换,因此将其关闭。
    ssl_session_tickets off;
    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_trusted_certificate cert/xxxxx.pem; # 证书地址
    resolver 8.8.8.8 202.106.0.20 valid=300s;
    resolver_timeout 5s;
}

参考资料

目录

Great! You've successfully subscribed.
Great! Next, complete checkout for full access.
Welcome back! You've successfully signed in.
Success! Your account is fully activated, you now have access to all content.