4
0
Эх сурвалжийг харах

refactor(static): use a simple struct instead of two slices to store assets data and checksums

- Use a simple struct instead of two slices to store the data and the checksums
  of resources
- Remove a superfluous call to Sprintf
- Factorise presence check and data retrieval in some maps
- Size the maps when possible
Julien Voisin 8 сар өмнө
parent
commit
798bc4cd2d

+ 23 - 19
internal/ui/static/static.go

@@ -15,12 +15,16 @@ import (
 	"github.com/tdewolff/minify/v2/js"
 )
 
+type asset struct {
+	Data     []byte
+	Checksum string
+}
+
 // Static assets.
 var (
-	StylesheetBundleChecksums map[string]string
-	StylesheetBundles         map[string][]byte
-	JavascriptBundleChecksums map[string]string
-	JavascriptBundles         map[string][]byte
+	StylesheetBundles   map[string]asset
+	JavascriptBundles   map[string]asset
+	binaryFileChecksums map[string]string
 )
 
 //go:embed bin/*
@@ -32,16 +36,13 @@ var stylesheetFiles embed.FS
 //go:embed js/*.js
 var javascriptFiles embed.FS
 
-var binaryFileChecksums map[string]string
-
 // CalculateBinaryFileChecksums generates hash of embed binary files.
 func CalculateBinaryFileChecksums() error {
-	binaryFileChecksums = make(map[string]string)
-
 	dirEntries, err := binaryFiles.ReadDir("bin")
 	if err != nil {
 		return err
 	}
+	binaryFileChecksums = make(map[string]string, len(dirEntries))
 
 	for _, dirEntry := range dirEntries {
 		data, err := LoadBinaryFile(dirEntry.Name())
@@ -57,15 +58,16 @@ func CalculateBinaryFileChecksums() error {
 
 // LoadBinaryFile loads an embed binary file.
 func LoadBinaryFile(filename string) ([]byte, error) {
-	return binaryFiles.ReadFile(fmt.Sprintf(`bin/%s`, filename))
+	return binaryFiles.ReadFile("bin/" + filename)
 }
 
 // GetBinaryFileChecksum returns a binary file checksum.
 func GetBinaryFileChecksum(filename string) (string, error) {
-	if _, found := binaryFileChecksums[filename]; !found {
+	data, found := binaryFileChecksums[filename]
+	if !found {
 		return "", fmt.Errorf(`static: unable to find checksum for %q`, filename)
 	}
-	return binaryFileChecksums[filename], nil
+	return data, nil
 }
 
 // GenerateStylesheetsBundles creates CSS bundles.
@@ -79,8 +81,7 @@ func GenerateStylesheetsBundles() error {
 		"system_sans_serif": {"css/system.css", "css/sans_serif.css", "css/common.css"},
 	}
 
-	StylesheetBundles = make(map[string][]byte)
-	StylesheetBundleChecksums = make(map[string]string)
+	StylesheetBundles = make(map[string]asset, len(bundles))
 
 	minifier := minify.New()
 	minifier.AddFunc("text/css", css.Minify)
@@ -102,8 +103,10 @@ func GenerateStylesheetsBundles() error {
 			return err
 		}
 
-		StylesheetBundles[bundle] = minifiedData
-		StylesheetBundleChecksums[bundle] = crypto.HashFromBytes(minifiedData)
+		StylesheetBundles[bundle] = asset{
+			Data:     minifiedData,
+			Checksum: crypto.HashFromBytes(minifiedData),
+		}
 	}
 
 	return nil
@@ -125,8 +128,7 @@ func GenerateJavascriptBundles() error {
 		},
 	}
 
-	JavascriptBundles = make(map[string][]byte)
-	JavascriptBundleChecksums = make(map[string]string)
+	JavascriptBundles = make(map[string]asset, len(bundles))
 
 	jsMinifier := js.Minifier{Version: 2020}
 
@@ -150,8 +152,10 @@ func GenerateJavascriptBundles() error {
 			return err
 		}
 
-		JavascriptBundles[bundle] = minifiedData
-		JavascriptBundleChecksums[bundle] = crypto.HashFromBytes(minifiedData)
+		JavascriptBundles[bundle] = asset{
+			Data:     minifiedData,
+			Checksum: crypto.HashFromBytes(minifiedData),
+		}
 	}
 
 	return nil

+ 3 - 3
internal/ui/static_javascript.go

@@ -21,14 +21,14 @@ const licenseSuffix = "\n//@license-end"
 
 func (h *handler) showJavascript(w http.ResponseWriter, r *http.Request) {
 	filename := request.RouteStringParam(r, "name")
-	etag, found := static.JavascriptBundleChecksums[filename]
+	js, found := static.JavascriptBundles[filename]
 	if !found {
 		html.NotFound(w, r)
 		return
 	}
 
-	response.New(w, r).WithCaching(etag, 48*time.Hour, func(b *response.Builder) {
-		contents := static.JavascriptBundles[filename]
+	response.New(w, r).WithCaching(js.Checksum, 48*time.Hour, func(b *response.Builder) {
+		contents := js.Data
 
 		if filename == "service-worker" {
 			variables := fmt.Sprintf(`const OFFLINE_URL=%q;`, route.Path(h.router, "offline"))

+ 3 - 3
internal/ui/static_stylesheet.go

@@ -15,15 +15,15 @@ import (
 
 func (h *handler) showStylesheet(w http.ResponseWriter, r *http.Request) {
 	filename := request.RouteStringParam(r, "name")
-	etag, found := static.StylesheetBundleChecksums[filename]
+	m, found := static.StylesheetBundles[filename]
 	if !found {
 		html.NotFound(w, r)
 		return
 	}
 
-	response.New(w, r).WithCaching(etag, 48*time.Hour, func(b *response.Builder) {
+	response.New(w, r).WithCaching(m.Checksum, 48*time.Hour, func(b *response.Builder) {
 		b.WithHeader("Content-Type", "text/css; charset=utf-8")
-		b.WithBody(static.StylesheetBundles[filename])
+		b.WithBody(m.Data)
 		b.Write()
 	})
 }

+ 4 - 4
internal/ui/view/view.go

@@ -41,10 +41,10 @@ func New(tpl *template.Engine, r *http.Request, sess *session.Session) *View {
 		"flashErrorMessage":    sess.FlashErrorMessage(request.FlashErrorMessage(r)),
 		"theme":                theme,
 		"language":             request.UserLanguage(r),
-		"theme_checksum":       static.StylesheetBundleChecksums[theme],
-		"app_js_checksum":      static.JavascriptBundleChecksums["app"],
-		"sw_js_checksum":       static.JavascriptBundleChecksums["service-worker"],
-		"webauthn_js_checksum": static.JavascriptBundleChecksums["webauthn"],
+		"theme_checksum":       static.StylesheetBundles[theme].Checksum,
+		"app_js_checksum":      static.JavascriptBundles["app"].Checksum,
+		"sw_js_checksum":       static.JavascriptBundles["service-worker"].Checksum,
+		"webauthn_js_checksum": static.JavascriptBundles["webauthn"].Checksum,
 		"webAuthnEnabled":      config.Opts.WebAuthn(),
 	}}
 }