client/web: add support for zst precomppressed assets

This will enable us to reduce the size of these embedded assets.

Updates tailscale/corp#20099

Signed-off-by: James Tucker <james@tailscale.com>
This commit is contained in:
James Tucker
2024-05-17 13:47:27 -07:00
parent adb7a86559
commit f39ac7d49c
10 changed files with 174 additions and 25 deletions

View File

@@ -17,8 +17,9 @@ import (
"path/filepath"
"github.com/andybalholm/brotli"
"github.com/klauspost/compress/zstd"
"golang.org/x/sync/errgroup"
"tailscale.com/tsweb"
"tailscale.com/tsweb/tswebutil"
)
// PrecompressDir compresses static assets in dirPath using Gzip and Brotli, so
@@ -63,13 +64,19 @@ type Options struct {
// OpenPrecompressedFile opens a file from fs, preferring compressed versions
// generated by PrecompressDir if possible.
func OpenPrecompressedFile(w http.ResponseWriter, r *http.Request, path string, fs fs.FS) (fs.File, error) {
if tsweb.AcceptsEncoding(r, "br") {
if tswebutil.AcceptsEncoding(r, "zstd") {
if f, err := fs.Open(path + ".zst"); err == nil {
w.Header().Set("Content-Encoding", "zstd")
return f, nil
}
}
if tswebutil.AcceptsEncoding(r, "br") {
if f, err := fs.Open(path + ".br"); err == nil {
w.Header().Set("Content-Encoding", "br")
return f, nil
}
}
if tsweb.AcceptsEncoding(r, "gzip") {
if tswebutil.AcceptsEncoding(r, "gzip") {
if f, err := fs.Open(path + ".gz"); err == nil {
w.Header().Set("Content-Encoding", "gzip")
return f, nil
@@ -104,6 +111,17 @@ func Precompress(path string, options Options) error {
if err != nil {
return err
}
zstdLevel := zstd.WithEncoderLevel(zstd.SpeedBestCompression)
if options.FastCompression {
zstdLevel = zstd.WithEncoderLevel(zstd.SpeedFastest)
}
err = writeCompressed(contents, func(w io.Writer) (io.WriteCloser, error) {
// Per RFC 8878, encoders should avoid window sizes larger than 8MB, which is the max that Chrome acccepts.
return zstd.NewWriter(w, zstdLevel, zstd.WithWindowSize(8<<20))
}, path+".zst", fi.Mode())
if err != nil {
return err
}
brotliLevel := brotli.BestCompression
if options.FastCompression {
brotliLevel = brotli.BestSpeed