salvo-compression
1
总安装量
1
周安装量
#53136
全站排名
安装命令
npx skills add https://github.com/salvo-rs/salvo-skills --skill salvo-compression
Agent 安装分布
amp
1
opencode
1
cursor
1
kimi-cli
1
codex
1
github-copilot
1
Skill 文档
Salvo Response Compression
This skill helps configure response compression in Salvo applications.
HTTP Compression Basics
HTTP compression reduces response size by compressing content before sending. The process:
- Client sends
Accept-Encoding: gzip, deflate, brheader - Server compresses response and sets
Content-Encoding: gzipheader - Client automatically decompresses the response
Setup
[dependencies]
salvo = { version = "0.89.0", features = ["compression"] }
Basic Usage
use salvo::prelude::*;
use salvo::compression::Compression;
#[handler]
async fn large_response() -> String {
"This response will be compressed if the client supports it. ".repeat(100)
}
#[tokio::main]
async fn main() {
let router = Router::new()
.hoop(Compression::new()) // Enable compression
.get(large_response);
let acceptor = TcpListener::new("0.0.0.0:8080").bind().await;
Server::new(acceptor).serve(router).await;
}
Supported Algorithms
Salvo supports four compression algorithms:
| Algorithm | Feature | Description |
|---|---|---|
| Gzip | Default | Most widely supported, good balance |
| Brotli (br) | Default | Best compression ratio, higher CPU |
| Zstd | Default | Fast with good compression |
| Deflate | Default | Legacy, rarely used alone |
Configuring Specific Algorithms
use salvo::compression::{Compression, CompressionLevel};
// Only gzip
let gzip_only = Compression::new()
.enable_gzip(CompressionLevel::Default);
// Only brotli
let brotli_only = Compression::new()
.enable_brotli(CompressionLevel::Best);
// Multiple algorithms
let multi = Compression::new()
.enable_gzip(CompressionLevel::Default)
.enable_brotli(CompressionLevel::Default)
.enable_zstd(CompressionLevel::Default);
Compression Levels
use salvo::compression::CompressionLevel;
// Available levels
CompressionLevel::Fastest // Fastest speed, lower compression
CompressionLevel::Default // Balanced speed and compression
CompressionLevel::Best // Best compression, slower
CompressionLevel::Precise(6) // Exact level (algorithm-specific)
Level Selection Guide
| Use Case | Recommended Level |
|---|---|
| Dynamic API responses | Fastest |
| Static assets | Best |
| General purpose | Default |
Minimum Response Size
Small responses may become larger after compression. Set a minimum threshold:
let compression = Compression::new()
.min_length(1024); // Only compress responses > 1KB
Content Type Filtering
Only compress text-based content (default behavior):
let compression = Compression::new()
.content_types(vec![
"text/html",
"text/css",
"text/javascript",
"application/json",
"application/xml",
"image/svg+xml",
]);
Algorithm Priority
When client supports multiple algorithms, set server preference:
let compression = Compression::new()
.force_priority(true); // Use server's priority order
// Default priority: Brotli > Zstd > Gzip > Deflate
Different Routes, Different Compression
use salvo::compression::{Compression, CompressionLevel};
use salvo::prelude::*;
#[tokio::main]
async fn main() {
// High compression for static assets
let static_compression = Compression::new()
.enable_brotli(CompressionLevel::Best)
.enable_gzip(CompressionLevel::Best);
// Fast compression for API
let api_compression = Compression::new()
.enable_gzip(CompressionLevel::Fastest)
.min_length(256);
let router = Router::new()
.push(
Router::with_path("static")
.hoop(static_compression)
.get(StaticDir::new("./public"))
)
.push(
Router::with_path("api")
.hoop(api_compression)
.get(api_handler)
);
let acceptor = TcpListener::new("0.0.0.0:8080").bind().await;
Server::new(acceptor).serve(router).await;
}
Pre-compressed Static Files
For best performance, pre-compress static files at build time:
# Pre-compress with gzip
gzip -k -9 ./public/bundle.js
# Pre-compress with brotli
brotli -k ./public/bundle.js
Then serve with static file handler that detects pre-compressed files.
Complete Example
use salvo::compression::{Compression, CompressionLevel};
use salvo::prelude::*;
use serde::Serialize;
#[derive(Serialize)]
struct LargeResponse {
items: Vec<String>,
}
#[handler]
async fn large_json() -> Json<LargeResponse> {
Json(LargeResponse {
items: (0..1000).map(|i| format!("Item {}", i)).collect(),
})
}
#[handler]
async fn html_page() -> Text<&'static str> {
Text::Html(r#"
<!DOCTYPE html>
<html>
<head><title>Compressed Page</title></head>
<body>
<h1>This page is compressed!</h1>
<p>The server compresses this HTML before sending it.</p>
</body>
</html>
"#)
}
#[tokio::main]
async fn main() {
let compression = Compression::new()
.enable_gzip(CompressionLevel::Default)
.enable_brotli(CompressionLevel::Default)
.min_length(512)
.content_types(vec![
"text/html",
"text/css",
"application/json",
"application/javascript",
]);
let router = Router::new()
.hoop(compression)
.push(Router::with_path("api/data").get(large_json))
.push(Router::with_path("page").get(html_page));
let acceptor = TcpListener::new("0.0.0.0:8080").bind().await;
Server::new(acceptor).serve(router).await;
}
Testing Compression
# Request with gzip support
curl -H "Accept-Encoding: gzip" -v http://localhost:8080/api/data
# Request with brotli support
curl -H "Accept-Encoding: br" -v http://localhost:8080/api/data
# Check response headers for Content-Encoding
Best Practices
- Use compression for text content: HTML, CSS, JS, JSON, XML
- Skip already compressed content: JPEG, PNG, MP4, ZIP
- Set minimum size threshold: Avoid compressing tiny responses
- Choose level based on content type: Static = Best, Dynamic = Fastest
- Pre-compress static assets: Build-time compression for best performance
- Monitor CPU usage: High compression levels increase CPU load
- Test with real clients: Verify compression works end-to-end
- Consider CDN compression: CDNs often handle compression for you