浏览器的 “压缩套餐”:原来它认识这么多 “打包方式”
先给压缩方法整个 “全家福”:浏览器是个挑剔的 “快递收件员”
想象你网购了一堆东西,快递员(浏览器)来收件时,只接受特定的打包方式(压缩方法)—— 有的认普通快递袋,有的认真空压缩袋,太新潮的可能还不认识。网页压缩也是一个道理:服务器把网页 “打包”(压缩),浏览器得认识这种 “打包方式” 才能正确 “拆包”(解压)。
目前浏览器主流支持的 “打包方式” 有 4 种,就像快递站的 4 种打包工具:
压缩方法 | 类比 | 特点 | 浏览器支持度 |
gzip | 普通快递袋 | 发明早、应用广,速度快但压缩率一般 | 几乎所有浏览器(包括古董级 IE6) |
Brotli | 真空压缩袋 Pro | 谷歌出品,压缩率高(比 gzip 小 10%-20%),稍慢 | 现代浏览器(Chrome 50+、Firefox 44 + 等) |
Deflate | 简易打包绳 | 比 gzip 稍简单,压缩率接近但应用少 | 大部分浏览器支持,但部分老浏览器有兼容问题 |
Zstd | 智能打包机 | Facebook 出品,速度和压缩率平衡,较新 | 较新浏览器(Chrome 113+、Firefox 112+) |
今天咱们就挨个扒一扒这些 “打包方式”,再写个工具让你的浏览器 “自报家门”—— 看看它认识哪几种。
案例 1:让浏览器 “坦白”:我支持哪些压缩方法?
浏览器在请求网页时,会在Accept-Encoding请求头里 “告诉” 服务器:“我认识这些打包方式,你随便用!” 咱们写个简单网页,用 JavaScript 读取这个请求头,让浏览器自己说出来。
步骤 1:创建检测页面(compression_check.html)
html
预览
<!DOCTYPE html>
<html>
<head>
<title>浏览器压缩支持检测</title>
<style>
body { font-family: Arial; max-width: 800px; margin: 20px auto; padding: 0 20px; }
.support-box { border: 2px solid #eee; padding: 15px; margin: 10px 0; border-radius: 8px; }
.supported { background: #f0fff4; border-color: #4cd964; }
.not-supported { background: #fff0f0; border-color: #ff9500; }
.title { font-weight: bold; font-size: 1.2em; margin-bottom: 10px; }
</style>
</head>
<body>
<h1>你的浏览器支持这些压缩方法吗?</h1>
<p>(浏览器会在请求头里偷偷告诉服务器它认识的压缩方式,下面是检测结果)</p>
<div id="result"></div>
<script>
// 注意:JavaScript在浏览器里不能直接读取请求头(出于安全限制)
// 所以咱们用一个小技巧:通过访问一个服务器端点获取请求头
// 这里为了简单,先模拟常见浏览器的情况,实际使用时需要后端配合
function detectCompressionSupport() {
// 模拟不同浏览器的Accept-Encoding(实际应从服务器获取)
// 真实场景中,后端可以读取请求头并返回给前端
const simulatedAcceptEncoding = "gzip, deflate, br, zstd"; // 现代Chrome的典型值
// 要检测的压缩方法
const compressions = [
{ name: "gzip", desc: "最常用的压缩方式,兼容性之王" },
{ name: "Brotli (br)", desc: "压缩率高,现代浏览器支持" },
{ name: "Deflate", desc: "较老的压缩方式,应用较少" },
{ name: "Zstd", desc: "较新的平衡型压缩方式" }
];
const resultDiv = document.getElementById("result");
compressions.forEach(comp => {
// 检查是否支持(忽略大小写)
const isSupported = simulatedAcceptEncoding.toLowerCase().includes(
comp.name.includes('(') ? comp.name.split('(')[1].replace(')', '') : comp.name
);
const box = document.createElement('div');
box.className = `support-box ${isSupported ? 'supported' : 'not-supported'}`;
box.innerHTML = `
<div class="title">${comp.name}:${isSupported ? ' 支持' : ' 不支持'}</div>
<div>${comp.desc}</div>
`;
resultDiv.appendChild(box);
});
// 显示原始请求头(模拟)
const headerDiv = document.createElement('div');
headerDiv.style.marginTop = "20px";
headerDiv.innerHTML = `<strong>模拟的Accept-Encoding请求头:</strong>${simulatedAcceptEncoding}`;
resultDiv.appendChild(headerDiv);
}
// 页面加载后检测
window.onload = detectCompressionSupport;
</script>
</body>
</html>
步骤 2:运行方法(超简单!)
- 把上面代码复制到文本编辑器,保存为compression_check.html(注意后缀是.html)。
- 双击这个文件,用你的浏览器打开(Chrome、Firefox、Edge 都行)。
预期效果:
页面会显示 4 种压缩方法的支持情况(基于模拟的现代浏览器数据),通常会看到:
- gzip: 支持
- Brotli (br): 支持
- Deflate: 支持
- Zstd: 支持(如果用的是较新浏览器)
如果用很老的浏览器(比如 IE8)打开,可能会看到 Brotli 和 Zstd 显示 “不支持”—— 这就是浏览器的 “代沟”~
案例 2:后端实战:根据浏览器支持动态选择压缩方法
光检测还不够,服务器得 “看菜下饭”—— 浏览器支持什么压缩,就用什么方法。咱们用 Rust 的hyper框架搭个服务器,实现这个逻辑。
步骤 1:创建 Rust 项目
bash
cargo new browser_compression_demo
cd browser_compression_demo
步骤 2:添加依赖(Cargo.toml)
toml
[dependencies]
hyper = { version = "1.1", features = ["full"] } # HTTP服务器
tokio = { version = "1.0", features = ["full"] } # 异步运行时
flate2 = "1.0" # gzip和Deflate压缩
brotli = "3.3" # Brotli压缩
zstd = "0.13" # Zstd压缩
步骤 3:服务器代码(src/main.rs)
rust
use brotli::enc::BrotliEncoderParams;
use brotli::BrotliCompress;
use flate2::write::{DeflateEncoder, GzEncoder};
use flate2::Compression;
use hyper::{
header::{ACCEPT_ENCODING, CONTENT_ENCODING, CONTENT_TYPE},
service::{make_service_fn, service_fn},
Body, Request, Response, Server,
};
use std::convert::Infallible;
use std::io::Write;
use std::net::SocketAddr;
use zstd::bulk::Compressor;
// 压缩内容:根据浏览器支持的方法选择最优解
fn compress_best(content: &str, accept_encoding: &str) -> (Vec<u8>, &'static str) {
// 优先级:Brotli > Zstd > gzip > Deflate > 不压缩
if accept_encoding.contains("br") {
// Brotli压缩
let mut params = BrotliEncoderParams::default();
params.quality = 6;
let mut compressed = Vec::new();
let mut encoder = BrotliCompress::from_params(content.as_bytes(), &mut compressed, Pms);
encoder.finish().unwrap();
(compressed, "br")
} else if accept_encoding.contains("zstd") {
// Zstd压缩
let mut compressor = Compressor::new(3).unwrap();
let compressed = compressor.compress(content.as_bytes()).unwrap();
(compressed, "zstd")
} else if accept_encoding.contains("gzip") {
// gzip压缩
let mut encoder = GzEncoder::new(Vec::new(), Compression::default());
encoder.write_all(content.as_bytes()).unwrap();
let compressed = encoder.finish().unwrap();
(compressed, "gzip")
} else if accept_encoding.contains("deflate") {
// Deflate压缩
let mut encoder = DeflateEncoder::new(Vec::new(), Compression::default());
encoder.write_all(content.as_bytes()).unwrap();
let compressed = encoder.finish().unwrap();
(compressed, "deflate")
} else {
// 不压缩
(content.as_bytes().to_vec(), "")
}
}
// 处理HTTP请求
async fn handle_request(req: Request<Body>) -> Result<Response<Body>, Infallible> {
// 要返回的网页内容
let html = r#"
<!DOCTYPE html>
<html>
<head>
<title>动态压缩测试</title>
</head>
<body>
<h1>服务器给你用了最优压缩方法!</h1>
<p>按F12→网络,看响应头Content-Encoding就知道用了啥~</p>
<p>内容越长,压缩效果越明显哦~</p>
</body>
</html>
"#;
// 获取浏览器支持的压缩方法
let accept_encoding = req.headers()
.get(ACCEPT_ENCODING)
.and_then(|h| h.to_str().ok())
.unwrap_or("");
// 选择最优压缩方法
let (compressed, encoding) = compress_best(html, accept_encoding);
// 构建响应
let mut response = Response::builder()
.header(CONTENT_TYPE, "text/html; charset=utf-8");
// 添加压缩方式头(如果用了压缩)
let response = if !encoding.is_empty() {
response.header(CONTENT_ENCODING, encoding)
} else {
response
}.body(Body::from(compressed)).unwrap();
Ok(response)
}
#[tokio::main]
async fn main() {
let addr = SocketAddr::from(([127, 0, 0, 1], 8080));
let make_svc = make_service_fn(|_conn| async {
Ok::<_, Infallible>(service_fn(handle_request))
});
let server = Server::bind(&addr).serve(make_svc);
println!("服务器启动!访问 http://127.0.0.1:8080");
if let Err(e) = server.await {
eprintln!("服务器出错:{}", e);
}
}
步骤 4:编译运行
bash
cargo run
打开浏览器访问http://127.0.0.1:8080,按 F12 查看 “网络” 标签:
- 现代 Chrome/Firefox 会显示Content-Encoding: br(Brotli,优先级最高)。
- 如果用较老的浏览器(比如 IE11),可能显示Content-Encoding: gzip。
- 极端情况(比如禁用所有压缩)会没有Content-Encoding头。
总结:浏览器的 “压缩菜单” 怎么点?
- 兼容性首选 gzip:像餐厅的 “招牌菜”,几乎所有人都能接受。
- 追求极致选 Brotli:适合现代浏览器用户,压缩率最高,像 “精致套餐”。
- 老系统用 Deflate:虽然不常用,但老浏览器可能只认它,像 “怀旧套餐”。
- 尝鲜选 Zstd:新浏览器支持,平衡速度和压缩率,像 “新品体验套餐”。
实际开发中,服务器通常会按 “Brotli> Zstd > gzip > Deflate” 的优先级选择,既保证多数用户体验,又不抛弃老系统 —— 就像餐厅既卖新品,也保留经典菜~
标题:
- 浏览器的 “压缩菜单”:从 gzip 到 Zstd 全解析
- 一文看懂:浏览器支持的 4 种网页压缩方法及实战
简介:
本文用快递打包的幽默类比,详解浏览器支持的 4 种网页压缩方法(gzip、Brotli、Deflate、Zstd),通过前端检测页面和后端动态选择案例,展示各方法的特点与使用场景,步骤清晰可实操,助你掌握网页压缩的 “点菜技巧”。
关键词:
#浏览器 #网页压缩 #gzip #Brotli #Zstd