我们相信:世界是美好的,你是我也是。 来玩一下解压小游戏吧!

在网站性能优化的众多手段中,资源压缩是降低传输体积、提升加载速度的关键一环。而提到压缩,大家最先想到的往往是Gzip,但近年来Brotli压缩凭借更优的压缩比和相近的解压效率,逐渐成为主流的优化选择。苏南大叔将在本文中对Brotil压缩,做个简单的入门介绍。并从浏览器支持检测、Nginx配置启用、PHP代码检测三个核心维度,手把手教你落地Brotli压缩方案。

苏南大叔:启用Brotli压缩:比Gzip更高效的性能优化方案 - Brotil性能优化方案
启用Brotli压缩:比Gzip更高效的性能优化方案(图4-1)

这里是苏南大叔的“程序如此灵动”博客,记录苏南大叔的代码编程经验总结。本文说明网络代码传输中的最新压缩算法Brotli。所以,曾经的霸主IE系列是不支持此算法的。本文测试环境:chrome@143.0.7499.170nginx@1.28.0php@7.4

对比gzip

先简单对比下BrotliGzip:两者均是主流的无损数据压缩算法,

  • Gzip基于DEFLATE算法,兼容性极佳。
  • BrotliGoogle研发,采用LZ77算法与霍夫曼编码结合的方式,在相同压缩级别下,对文本类资源(HTMLCSSJSJSON等)的压缩率比Gzip高15%-20%,能进一步减少带宽消耗和加载时间。

不过Brotli的兼容性略逊于Gzip(现代主流浏览器均支持,老旧浏览器如IE不支持),因此实际应用中常采用“Brotli优先,Gzip兜底”的策略。

浏览器是否支持Brotli压缩

浏览器对Brotli的支持是启用该压缩的前提,可以通过浏览器开发者工具快速检测:

  1. 切换到“Network(网络)”面板,勾选上方的“Disable cache(禁用缓存)”,避免缓存影响检测结果;
  2. 刷新页面,在网络请求列表中,任意点击一个文本类资源(如HTML文档、CSS文件、JS文件);
  3. 在右侧弹出的详情面板中,查看“Response Headers(响应头)”:若存在 Content-Encoding: br 字段,则说明浏览器支持Brotli,且服务器已启用该压缩;若字段为Content-Encoding: gzip 则为Gzip压缩;若无该字段则未启用压缩。

苏南大叔:启用Brotli压缩:比Gzip更高效的性能优化方案 - 浏览器端检测是否支持Brotil压缩
启用Brotli压缩:比Gzip更高效的性能优化方案(图4-2)

除了通过开发者工具,也可以通过在线工具(如Can I Use)查询不同浏览器对Brotli的支持情况。网址如下:

苏南大叔:启用Brotli压缩:比Gzip更高效的性能优化方案 - 浏览器支持情况一览表
启用Brotli压缩:比Gzip更高效的性能优化方案(图4-3)

Nginx中判断Brotli压缩

截至到发稿,Nginx本身不自带Brotli模块,需要先安装对应的扩展模块,再通过配置启用。是否安装了Brotil模块,可以通过观察如下命令的输出查看。

nginx -V

苏南大叔:启用Brotli压缩:比Gzip更高效的性能优化方案 - nginx-v
启用Brotli压缩:比Gzip更高效的性能优化方案(图4-4)

安装Nginx Brotli模块

首先确认Nginx的安装路径和版本,避免模块与Nginx版本不兼容。推荐通过源码编译安装模块,步骤如下:

下载Brotli模块源码:

git clone https://github.com/google/ngx_brotli.git
cd ngx_brotli
git submodule update --init

进入Nginx源码目录(若已安装Nginx,需找到当初编译安装的源码包;若未安装,先下载对应版本的Nginx源码)。重新编译Nginx,添加Brotli模块(原有配置需保留,避免覆盖已有的模块):

./configure --prefix=/usr/local/nginx  # 此处保留原有configure参数,新增以下两个模块
--add-module=/path/to/ngx_brotli  # 替换为实际的ngx_brotli目录路径
--add-module=/path/to/ngx_brotli/dynamic
make && make install

编译完成后,通过 nginx -V 命令查看配置,若输出中包含 --add-module=/path/to/ngx_brotli 则说明模块安装成功。

Nginx启用Brotli

编辑Nginx的主配置文件(通常位于/usr/local/nginx/conf/nginx.conf/etc/nginx/nginx.conf),在 http 块中添加以下配置:

# 启用Brotli压缩
brotli on;
# 压缩级别(1-11,级别越高压缩率越高,但CPU消耗越大,推荐5-6)
brotli_comp_level 6;
# 最小压缩文件大小(小于该大小的文件不压缩,单位字节)
brotli_min_length 1000;
# 压缩的文件类型(重点压缩文本类资源)
brotli_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript application/vnd.ms-fontobject application/x-font-ttf font/opentype image/svg+xml image/x-icon;
# 启用静态文件压缩缓存(避免重复压缩,提升性能)
brotli_static on;
# 添加Vary头,告知CDN根据Accept-Encoding返回对应压缩文件
add_header Vary Accept-Encoding;
# 保留Gzip配置作为兜底(针对不支持Brotli的浏览器)
gzip on;
gzip_comp_level 6;
gzip_min_length 1000;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

配置完成后,检查配置文件语法是否正确:nginx -t,若提示“test is successful”则配置无误,重启Nginx生效:nginx -s reload

PHP代码中检测Brotli压缩是否启用

PHP中,我们可以通过检测服务器响应头或PHP环境变量,判断Brotli压缩是否启用。

检测自身服务器

通过 headers_list() 函数获取当前脚本的响应头,判断是否存在Content-Encoding: br字段,代码示例:

// 必须在输出任何内容之前调用(因为响应头需在内容输出前发送)
header('Content-Type: text/html; charset=utf-8');

// 获取当前响应头列表
$headers = headers_list();
$isBrotliEnabled = false;

foreach ($headers as $header) {
    // 忽略大小写匹配响应头
    if (stripos($header, 'Content-Encoding: br') !== false) {
        $isBrotliEnabled = true;
        break;
    }
}

if ($isBrotliEnabled) {
    echo "Brotli压缩已启用";
} else {
    // 可进一步检测是否启用Gzip
    $isGzipEnabled = false;
    foreach ($headers as $header) {
        if (stripos($header, 'Content-Encoding: gzip') !== false) {
            $isGzipEnabled = true;
            break;
        }
    }
    echo $isGzipEnabled ? "Gzip压缩已启用" : "未启用任何压缩";
}

检测别人的服务器

若需要检测非php自身服务器资源的Brotli启用情况,可以通过PHPcURL函数发送请求,获取目标资源的响应头,代码示例:

function checkBrotliSupport($url) {
    $ch = curl_init();
    // 设置请求URL
    curl_setopt($ch, CURLOPT_URL, $url);
    // 只获取响应头,不获取响应体
    curl_setopt($ch, CURLOPT_HEADER, true);
    curl_setopt($ch, CURLOPT_NOBODY, true);
    // 允许跟随重定向
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    // 设置请求头,告知服务器优先使用Brotli压缩
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'Accept-Encoding: br, gzip, deflate'
    ]);
    // 执行请求并获取响应头
    $response = curl_exec($ch);
    curl_close($ch);

    // 匹配Content-Encoding字段
    if (preg_match('/Content-Encoding:\s*br/i', $response)) {
        return "目标资源已启用Brotli压缩";
    } elseif (preg_match('/Content-Encoding:\s*gzip/i', $response)) {
        return "目标资源已启用Gzip压缩";
    } else {
        return "目标资源未启用压缩";
    }
}

// 调用函数检测(替换为需要检测的资源URL)
echo checkBrotliSupport('https://your-domain.com/index.html');

注意事项:使用cURL检测时,需确保PHP环境已启用cURL扩展;同时,若目标资源存在CDN缓存,需考虑缓存对响应头的影响,可添加缓存控制头或刷新CDN后再检测。

相关文章

总结

Brotli作为比Gzip更高效的压缩算法,能有效减少网站资源传输体积,提升加载速度。落地Brotli压缩的核心步骤为:先通过浏览器开发者工具确认浏览器支持情况,再在Nginx中安装模块并配置启用,最后可通过PHP代码验证压缩是否生效。实际应用中,建议保留Gzip配置作为兜底,确保老旧浏览器的兼容性。通过这一系列操作,就能轻松完成Brotli压缩的部署,为用户带来更流畅的访问体验。

更多苏南大叔的编程经验文字,可以参考:

如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。

 【福利】 腾讯云最新爆款活动!1核2G云服务器首年50元!

 【源码】本文代码片段及相关软件,请点此获取更多信息

 【绝密】秘籍文章入口,仅传授于有缘之人   nginx