Compression across the board: directory answers, uploads, metrics, traces, the page (#253)
Measured 2026-10-16, uncompressed until now: the directory's answers (the feed list ipx reads, 603 KB of JSON, ~134 ms of a 159 ms Directory request), ipx's snapshot upload (~100 KB each half hour), both /metrics (4.7 and 0.9 KB every 15 s) and every trace export to Tempo. Already compressed: ipx-web's answers (zstd, #239), the home page and the directory's public pages through Cloudflare (brotli, zstd). - The directory compresses with brotli, zstd or gzip as asked, and unpacks a gzipped request. - ipx sends its snapshot gzipped; the directory is deployed first. - Both /metrics answer gzipped, as Prometheus asks. - opentelemetry-otlp's gzip-http: OTEL_EXPORTER_OTLP_COMPRESSION=gzip compresses the export, set for all three in production's compose file; Caddy's exporter reads the same variable. - web/build.mjs writes .br (quality 11) and .gz (level 9) beside each text file, and Caddy serves them in place (file_server precompressed): app.js 30 KB where zstd on the fly gave 37, app.css 11 where 14. A .br or .gz asked for by name is refused, or /admin.js.br would be the admin page's script without the check that keeps it to admins; in a handle of its own, since a bare respond runs after the handles. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -63,6 +63,15 @@ http://{$WEB_BIND::8080} {
|
||||
@compress not path /api/events /media/*
|
||||
encode @compress zstd gzip
|
||||
|
||||
# The copies web/build.mjs compressed are served in place of their file, never asked for by
|
||||
# name: /admin.js.br would be the admin page's script without the check below that keeps it to
|
||||
# admins (#253).
|
||||
# A handle of its own: a bare respond runs after the handles, and the last one serves any file.
|
||||
@packed path *.br *.gz
|
||||
handle @packed {
|
||||
respond 404
|
||||
}
|
||||
|
||||
# Before anything else, so no page or API call sees them: only ipx sets these.
|
||||
@forged not remote_ip {$TUNNEL_PEER:255.255.255.255}
|
||||
request_header @forged -Cf-Access-Authenticated-User-Email
|
||||
@@ -97,7 +106,9 @@ http://{$WEB_BIND::8080} {
|
||||
rewrite / /index.html
|
||||
rewrite /admin /admin.html
|
||||
header Cache-Control no-cache
|
||||
file_server
|
||||
file_server {
|
||||
precompressed br gzip
|
||||
}
|
||||
}
|
||||
|
||||
# The sign-in form, except for someone Cloudflare Access vouches for, who is sent to the app.
|
||||
@@ -108,7 +119,9 @@ http://{$WEB_BIND::8080} {
|
||||
}
|
||||
rewrite * /login.html
|
||||
header Cache-Control no-cache
|
||||
file_server
|
||||
file_server {
|
||||
precompressed br gzip
|
||||
}
|
||||
}
|
||||
|
||||
# Scripts and the stylesheet are named by a hash of their contents (web/build.mjs), so a browser
|
||||
@@ -120,6 +133,8 @@ http://{$WEB_BIND::8080} {
|
||||
@icons path *.png *.svg *.ico *.woff2
|
||||
header @icons Cache-Control "public, max-age=86400"
|
||||
handle {
|
||||
file_server
|
||||
file_server {
|
||||
precompressed br gzip
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user