必须在nginx层面启用gzip与brotli双算法协商机制,而非php层压缩:现代浏览器优先用brotli(压缩率高15%~30%),旧浏览器自动回退gzip,通过accept-encoding智能分发,并需关闭zlib.output_compression及ob_gzhandler避免冲突。

要让PHP框架(如Laravel、ThinkPHP、CodeIgniter)输出的HTML、CSS、JS等静态资源在传输时自动压缩,必须绕过PHP层手动压缩的陷阱,直接在Web服务器层面启用Gzip与Brotli双算法协商机制——这是唯一能兼顾兼容性、性能与HTTP/2友好性的方案。
确认当前压缩状态是否生效
打开Chrome DevTools → Network → 刷新页面 → 找到任意一个.css或.js请求 → 点击进入详情 → 查看Response Headers中的【Content-Encoding】字段值。若为gzip或br,说明已生效;若为空或显示identity,说明压缩未触发。同时检查【Vary: Accept-Encoding】是否存在,缺失会导致CDN缓存污染。
别信构建产物体积:main.js.gz文件再小,只要响应头没Content-Encoding,浏览器收到的就是明文。
在Nginx中同时开启Gzip与Brotli
确保二者共存而非互斥——现代Nginx支持按Accept-Encoding自动协商,客户端发br,gzip,服务端优先回br;遇到strip br头的老旧代理,则fallback到gzip,不会退化成明文。
第一步:确认Nginx已编译ngx_brotli模块。若未安装,需先执行cd /www/server && git clone https://github.com/google/ngx_brotli.git,再通过宝塔面板「编译安装」并勾选该模块;否则brotli on;将被忽略。
第二步:编辑Nginx主配置文件(通常位于/www/server/nginx/conf/nginx.conf),在http块内插入以下配置(位置必须在gzip配置之后,但仍在server块之外):
brotli on;
brotli_comp_level 5;
brotli_min_length 1024;
brotli_types text/plain text/css application/javascript application/json application/xml text/html image/svg+xml;
brotli_static off;
gzip on;
gzip_comp_level 6;
gzip_min_length 1024;
gzip_types text/plain text/css application/javascript application/json application/xml text/html image/svg+xml;
第三步:重载Nginx配置:nginx -t && nginx -s reload。注意:若使用宝塔,请点击【重载配置】而非【重启】,避免中断连接。
排除PHP层干扰:禁用zlib.output_compression
PHP 8.4中zlib.output_compression已被标记为deprecated,且强制启用会导致Content-Length计算错误、Chrome截断响应、与Transfer-Encoding: chunked冲突。必须关闭它。
编辑对应PHP版本的php.ini(可通过宝塔面板【PHP管理】→【配置文件】定位),找到zlib.output_compression行,将其设为Off:
【zlib.output_compression = Off】
同时删除或注释掉任何ob_start('ob_gzhandler')调用——PHP框架底层(如Laravel的Stack Middleware)若自行启用该函数,会与Nginx压缩叠加,导致响应体损坏。
验证预生成Brotli文件是否被正确服务
方法一:启用brotli_static on(需配合预生成.br文件)
将main.js用brotli命令压缩:brotli --quality=9 --output=main.js.br main.js,保持同目录。然后在Nginx location块中添加:brotli_static on;。此模式下Nginx直接返回.br文件,跳过运行时压缩,CPU开销归零。
方法二:不启用brotli_static,依赖实时压缩
适用于动态生成的JS/CSS(如Laravel Mix每次build后路径带hash)。此时必须确保Nginx的brotli_types包含application/javascript,并且响应Content-Type正确。PHP框架若输出时未显式设置header('Content-Type: application/javascript; charset=utf-8'),Nginx可能因类型不匹配而跳过压缩。
注意:.br文件权限需与源文件一致,否则Nginx会静默降级为发送原始文件。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











