admin: pre-gzip embedded static assets, add cache headers (#9918)

The admin UI served embedded static files uncompressed and without
cache headers: embed.FS has zero mod times, so no Last-Modified, no
ETag, no 304s -- every page load re-downloaded ~700KB of css/js in
full, which gets painful over slow or tunneled links.

Gzip the static tree at generation time (go generate ./weed/admin)
and embed only the compressed mirror, shrinking the binary ~1.5MB.
The handler hands the pre-compressed bytes to gzip-capable clients,
decompresses for the rest, and sets Cache-Control, per-variant
content-hash ETags and Vary so repeat loads revalidate with a 304.
bootstrap.min.css goes 232KB -> 30KB on the wire.

A drift test keeps static_gz/ in sync with static/.
This commit is contained in:
Chris Lu
2026-06-10 12:54:36 -07:00
committed by GitHub
parent c2271d59bb
commit e56a1c4c05
24 changed files with 406 additions and 17 deletions
+3 -9
View File
@@ -360,15 +360,9 @@ func startAdminServer(ctx context.Context, options AdminOptions, enableUI bool,
SameSite: http.SameSiteLaxMode,
}
// Static files - serve from embedded filesystem
staticFS, err := admin.GetStaticFS()
if err != nil {
log.Printf("Warning: Failed to load embedded static files: %v", err)
} else {
staticHandler := http.FileServer(http.FS(staticFS))
r.Handle("/static", http.RedirectHandler("/static/", http.StatusMovedPermanently))
r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", staticHandler))
}
// Static files - pre-gzipped and embedded in the binary
r.Handle("/static", http.RedirectHandler("/static/", http.StatusMovedPermanently))
r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", admin.StaticHandler()))
// Create admin server (plugin is always enabled)
adminServer := dash.NewAdminServer(*options.master, nil, dataDir, icebergPort)