From c84b0aa4334a68b4b8f74a6f73590459870ede5b Mon Sep 17 00:00:00 2001 From: Azareal Date: Fri, 19 Apr 2019 20:39:17 +1000 Subject: [PATCH] Avoid concatenating the style / script names with the hashes in AddScript, AddPreScriptAsync, AddScriptAsync and AddSheet to reduce the number of allocations. Use a string builder for building Link Headers. --- common/files.go | 7 ++++--- common/pages.go | 9 +++++---- common/theme.go | 2 +- routes/common.go | 23 ++++++++++++++++------- 4 files changed, 26 insertions(+), 15 deletions(-) diff --git a/common/files.go b/common/files.go index a8ca909a..82a08002 100644 --- a/common/files.go +++ b/common/files.go @@ -28,6 +28,7 @@ type SFile struct { Data []byte GzipData []byte Sha256 string + OName string Pos int64 Length int64 GzipLength int64 @@ -242,7 +243,7 @@ func (list SFileList) JSTmplInit() error { hasher.Write(data) checksum := hex.EncodeToString(hasher.Sum(nil)) - list.Set("/static/"+path, SFile{data, gzipData, checksum, 0, int64(len(data)), int64(len(gzipData)), mime.TypeByExtension(ext), f, f.ModTime().UTC().Format(http.TimeFormat)}) + list.Set("/static/"+path, SFile{data, gzipData, checksum,path + "?h=" + checksum, 0, int64(len(data)), int64(len(gzipData)), mime.TypeByExtension(ext), f, f.ModTime().UTC().Format(http.TimeFormat)}) DebugLogf("Added the '%s' static file.", path) return nil @@ -287,7 +288,7 @@ func (list SFileList) Init() error { } } - list.Set("/static/"+path, SFile{data, gzipData, checksum, 0, int64(len(data)), int64(len(gzipData)), mimetype, f, f.ModTime().UTC().Format(http.TimeFormat)}) + list.Set("/static/"+path, SFile{data, gzipData, checksum,path + "?h=" + checksum, 0, int64(len(data)), int64(len(gzipData)), mimetype, f, f.ModTime().UTC().Format(http.TimeFormat)}) DebugLogf("Added the '%s' static file.", path) return nil @@ -320,7 +321,7 @@ func (list SFileList) Add(path string, prefix string) error { hasher.Write(data) checksum := hex.EncodeToString(hasher.Sum(nil)) - list.Set("/static"+path, SFile{data, gzipData, checksum, 0, int64(len(data)), int64(len(gzipData)), mime.TypeByExtension(ext), f, f.ModTime().UTC().Format(http.TimeFormat)}) + list.Set("/static"+path, SFile{data, gzipData, checksum,path + "?h=" + checksum, 0, int64(len(data)), int64(len(gzipData)), mime.TypeByExtension(ext), f, f.ModTime().UTC().Format(http.TimeFormat)}) DebugLogf("Added the '%s' static file", path) return nil diff --git a/common/pages.go b/common/pages.go index 8c85af1e..d3f9257b 100644 --- a/common/pages.go +++ b/common/pages.go @@ -51,12 +51,13 @@ type Header struct { } func (header *Header) AddScript(name string) { + // TODO: Use a secondary static file map to avoid this concatenation? fname := "/static/" + name var oname string if fname[0] == '/' && fname[1] != '/' { file, ok := StaticFiles.Get(fname) if ok { - oname = name + "?h=" + file.Sha256 + oname = file.OName } } if oname == "" { @@ -72,7 +73,7 @@ func (header *Header) AddPreScriptAsync(name string) { if fname[0] == '/' && fname[1] != '/' { file, ok := StaticFiles.Get(fname) if ok { - oname = name + "?h=" + file.Sha256 + oname = file.OName } } if oname == "" { @@ -87,7 +88,7 @@ func (header *Header) AddScriptAsync(name string) { if fname[0] == '/' && fname[1] != '/' { file, ok := StaticFiles.Get(fname) if ok { - oname = name + "?h=" + file.Sha256 + oname = file.OName } } if oname == "" { @@ -106,7 +107,7 @@ func (header *Header) AddSheet(name string) { if fname[0] == '/' && fname[1] != '/' { file, ok := StaticFiles.Get(fname) if ok { - oname = name + "?h=" + file.Sha256 + oname = file.OName } } if oname == "" { diff --git a/common/theme.go b/common/theme.go index 626feeab..0402b654 100644 --- a/common/theme.go +++ b/common/theme.go @@ -165,7 +165,7 @@ func (theme *Theme) AddThemeStaticFiles() error { hasher.Write(data) checksum := hex.EncodeToString(hasher.Sum(nil)) - StaticFiles.Set("/static/"+theme.Name+path, SFile{data, gzipData, checksum, 0, int64(len(data)), int64(len(gzipData)), mime.TypeByExtension(ext), f, f.ModTime().UTC().Format(http.TimeFormat)}) + StaticFiles.Set("/static/"+theme.Name+path, SFile{data, gzipData, checksum,theme.Name+path + "?h=" + checksum, 0, int64(len(data)), int64(len(gzipData)), mime.TypeByExtension(ext), f, f.ModTime().UTC().Format(http.TimeFormat)}) DebugLog("Added the '/" + theme.Name + path + "' static file for theme " + theme.Name + ".") return nil diff --git a/routes/common.go b/routes/common.go index d0b100dd..707bf527 100644 --- a/routes/common.go +++ b/routes/common.go @@ -21,14 +21,20 @@ func ParseSEOURL(urlBit string) (slug string, id int, err error) { return halves[0], tid, err } +var slen1 = len("; rel=preload; as=script,") +var slen2 = len("; rel=preload; as=style,") + func doPush(w http.ResponseWriter, header *c.Header) { //fmt.Println("in doPush") if c.Config.EnableCDNPush { - // TODO: Faster string building... - var sbuf string + // TODO: Cache these in a sync.Pool? + var sb strings.Builder var push = func(in []string) { + sb.Grow((slen1 + 5) * len(in)) for _, path := range in { - sbuf += "; rel=preload; as=script," + sb.WriteString("; rel=preload; as=script,") } } push(header.Scripts) @@ -36,15 +42,18 @@ func doPush(w http.ResponseWriter, header *c.Header) { push(header.ScriptsAsync) if len(header.Stylesheets) > 0 { + sb.Grow((slen2 + 6) * len(header.Stylesheets)) for _, path := range header.Stylesheets { - sbuf += "; rel=preload; as=style," + sb.WriteString("; rel=preload; as=style,") } } // TODO: Push avatars? - if len(sbuf) > 0 { - sbuf = sbuf[:len(sbuf)-1] - w.Header().Set("Link", sbuf) + if sb.Len() > 0 { + sbuf := sb.String() + w.Header().Set("Link", sbuf[:len(sbuf)-1]) } } else if !c.Config.DisableServerPush { //fmt.Println("push enabled")