Build or update the BlueBubbles external channel plugin for Moltbot (extension package, REST...
npx skills add salvo-rs/salvo-skills --skill "salvo-compression"
Install specific skill from multi-skill repository
# Description
Compress HTTP responses using gzip, brotli, zstd, or deflate. Use for reducing bandwidth and improving load times.
# SKILL.md
name: salvo-compression
description: Compress HTTP responses using gzip, brotli, zstd, or deflate. Use for reducing bandwidth and improving load times.
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 = "1.88.1", 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
# Supported AI Coding Agents
This skill is compatible with the SKILL.md standard and works with all major AI coding agents:
Learn more about the SKILL.md standard and how to use these skills with your preferred AI coding agent.