全站资源传输优化说明
本文记录一次"以实测数据驱动"的传输优化:首页传输量 717.4 KB → 10.2 KB(-98.6%)。 优化对象是静态资源与传输层;内容图片(用户上传)本来就走
img-proxy.php(按需缩放 + WebP 缓存),未受影响。
一、优化前的实测审计
| 项目 | 实测结果 | 问题 |
|---|---|---|
| 首页传输量 | 717.4 KB(压缩后) | 其中 670 KB 是两张静态图 |
assets/images/qdcms-logo.png | 1024×1024 RGBA PNG,368,456 B | 页面按 32×32 显示 → 99.9% 像素被浪费 |
favicon.png | 1024×1024 RGBA PNG,302,076 B | favicon 标准尺寸 32×32 / apple-touch 180×180 |
| 静态资源缓存头 | /assets/**、/uploads/** 无 Cache-Control/Expires(只有 ETag) | 每次导航都要发条件请求(多一次 RTT/资源) |
| gzip | 已启用(level 2),HTML 31,760→5,653 B、CSS 26,987→7,845 B | 等级偏低;gzip_types 缺 application/json、image/svg+xml、text/xml |
client_max_body_size | nginx 50m,而 php.ini post_max_size=600M/upload_max_filesize=500M | 大视频上传会被 nginx 先拒(与 PHP 口径不一致) |
| 上传 MP4 | 3 个文件均为 faststart(moov 前置),Range 请求返回 206(64 KB / 1.1 ms) | 无需处理 ✓ |
| 内容图片 | img-proxy.php + uploads/_cache/*.webp | 已有 WebP/缩放机制 ✓ |
二、优化内容
1. 静态图瘦身(最大收益,-98%)
| 文件 | 前 | 后 | 尺寸 | 说明 |
|---|---|---|---|---|
assets/images/qdcms-logo.png | 368,456 B | 6,739 B(-98.2%) | 1024² → 256² | 页面按 32px 显示,256 = 8× 余量 |
favicon.png | 302,076 B | 4,761 B(-98.4%) | 1024² → 180² | favicon + apple-touch-icon 标准尺寸 |
- 保留原路径,全站 15 处引用无需改动;透明通道保留(PNG 调色板量化 128 色)
- 原图备份在交付包外(
qdcms-release/asset-backup/),需要回滚可直接替换
2. 随包工具:install/optimize-static-images.php
给客户的复用工具(CLI,GD 扩展,默认只预演):
php install/optimize-static-images.php # 预演:列出可优化文件与预计收益
php install/optimize-static-images.php --apply # 执行(原图备份为 <文件>.bak-optimize)
php install/optimize-static-images.php --apply --max=1600 # 自定义其余图片的长边上限(默认 1280)
规则:favicon.png → 180;assets/images/qdcms-logo.png → 256;其余 assets/images/** 超过 --max(默认 1280,避免误缩竖版海报)才处理。
实测:2400×1600 JPEG 干跑 120 KB → 3.4 KB(-97.1%)。
3. nginx 传输层(nginx.conf.example 已内置,本次线上已应用)
location ^~ /assets/css/ { expires 30d; access_log off; }
location ^~ /assets/js/ { expires 30d; access_log off; }
location ^~ /assets/im-plugin/ { expires 30d; access_log off; }
location ^~ /assets/images/ { expires 7d; access_log off; }
location = /favicon.png { expires 7d; access_log off; }
location ^~ /uploads/ { expires 7d; access_log off; }
- CSS/JS 由
assetVersion()追加?v=<filemtime>,内容变则 URL 变 → 长缓存安全; 图像/上传内容文件名含时间戳(不可变)→ 7 天,兼顾"换图尽快生效" gzip_comp_level 2 → 5;gzip_types增补application/json image/svg+xml text/xmlopen_file_cache max=10000 inactive=30s; open_file_cache_valid 60s; open_file_cache_min_uses 2;client_max_body_size 50m → 600m(与 php.ini 对齐,否则大视频上传 413)
4. 前端与视频(现状已达标,无需改动)
assets/js/img-lazy.js:列表图懒加载;XDImgUrl()→img-proxy.php(按需缩放 + WebP 缓存)- 视频:
preload="none"/"metadata"+ poster;上传 MP4 均 faststart;Range 可用(可拖动) - 若将来上 TLS,建议开启 HTTP/2(多路复用,进一步减少并发请求的队头阻塞)
三、优化效果(实测)
| 指标 | 优化前 | 优化后 |
|---|---|---|
| 首页传输量(HTML + 14 个资源,压缩后) | 717.4 KB | 10.2 KB(-98.6%) |
| 其中两张静态图 | 670.5 KB | 11.5 KB(-98.3%) |
| 静态资源二次访问 | 每个资源一次条件请求 | 30 天/7 天内直接命中缓存,0 请求 |
| 大文件上传上限 | nginx 50m 先拒 | 600m(与 PHP 一致) |
四、复验方法
# 1) 图片规格与体积
php install/optimize-static-images.php # 应全部显示"已达标"
# 2) 缓存头(重载 nginx 后)
curl -sI -H "Host: 你的域名" http://127.0.0.1/assets/css/style.css | grep -i cache-control
curl -sI -H "Host: 你的域名" http://127.0.0.1/favicon.png | grep -i cache-control
# 3) 压缩比
curl -s -o /dev/null -w "%{size_download}
" -H "Host: 你的域名" http://127.0.0.1/
curl -s -o /dev/null -w "%{size_download}
" --compressed -H "Host: 你的域名" http://127.0.0.1/
注意:本页所有体积均为压缩后(
--compressed)实测值;缓存头需重载 nginx 后生效。