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.
This commit is contained in:
Azareal 2019-04-19 20:39:17 +10:00
parent 42b9f27c45
commit c84b0aa433
4 changed files with 26 additions and 15 deletions

View File

@ -28,6 +28,7 @@ type SFile struct {
Data []byte Data []byte
GzipData []byte GzipData []byte
Sha256 string Sha256 string
OName string
Pos int64 Pos int64
Length int64 Length int64
GzipLength int64 GzipLength int64
@ -242,7 +243,7 @@ func (list SFileList) JSTmplInit() error {
hasher.Write(data) hasher.Write(data)
checksum := hex.EncodeToString(hasher.Sum(nil)) 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) DebugLogf("Added the '%s' static file.", path)
return nil 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) DebugLogf("Added the '%s' static file.", path)
return nil return nil
@ -320,7 +321,7 @@ func (list SFileList) Add(path string, prefix string) error {
hasher.Write(data) hasher.Write(data)
checksum := hex.EncodeToString(hasher.Sum(nil)) 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) DebugLogf("Added the '%s' static file", path)
return nil return nil

View File

@ -51,12 +51,13 @@ type Header struct {
} }
func (header *Header) AddScript(name string) { func (header *Header) AddScript(name string) {
// TODO: Use a secondary static file map to avoid this concatenation?
fname := "/static/" + name fname := "/static/" + name
var oname string var oname string
if fname[0] == '/' && fname[1] != '/' { if fname[0] == '/' && fname[1] != '/' {
file, ok := StaticFiles.Get(fname) file, ok := StaticFiles.Get(fname)
if ok { if ok {
oname = name + "?h=" + file.Sha256 oname = file.OName
} }
} }
if oname == "" { if oname == "" {
@ -72,7 +73,7 @@ func (header *Header) AddPreScriptAsync(name string) {
if fname[0] == '/' && fname[1] != '/' { if fname[0] == '/' && fname[1] != '/' {
file, ok := StaticFiles.Get(fname) file, ok := StaticFiles.Get(fname)
if ok { if ok {
oname = name + "?h=" + file.Sha256 oname = file.OName
} }
} }
if oname == "" { if oname == "" {
@ -87,7 +88,7 @@ func (header *Header) AddScriptAsync(name string) {
if fname[0] == '/' && fname[1] != '/' { if fname[0] == '/' && fname[1] != '/' {
file, ok := StaticFiles.Get(fname) file, ok := StaticFiles.Get(fname)
if ok { if ok {
oname = name + "?h=" + file.Sha256 oname = file.OName
} }
} }
if oname == "" { if oname == "" {
@ -106,7 +107,7 @@ func (header *Header) AddSheet(name string) {
if fname[0] == '/' && fname[1] != '/' { if fname[0] == '/' && fname[1] != '/' {
file, ok := StaticFiles.Get(fname) file, ok := StaticFiles.Get(fname)
if ok { if ok {
oname = name + "?h=" + file.Sha256 oname = file.OName
} }
} }
if oname == "" { if oname == "" {

View File

@ -165,7 +165,7 @@ func (theme *Theme) AddThemeStaticFiles() error {
hasher.Write(data) hasher.Write(data)
checksum := hex.EncodeToString(hasher.Sum(nil)) 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 + ".") DebugLog("Added the '/" + theme.Name + path + "' static file for theme " + theme.Name + ".")
return nil return nil

View File

@ -21,14 +21,20 @@ func ParseSEOURL(urlBit string) (slug string, id int, err error) {
return halves[0], tid, err return halves[0], tid, err
} }
var slen1 = len("</static/>; rel=preload; as=script,")
var slen2 = len("</static/>; rel=preload; as=style,")
func doPush(w http.ResponseWriter, header *c.Header) { func doPush(w http.ResponseWriter, header *c.Header) {
//fmt.Println("in doPush") //fmt.Println("in doPush")
if c.Config.EnableCDNPush { if c.Config.EnableCDNPush {
// TODO: Faster string building... // TODO: Cache these in a sync.Pool?
var sbuf string var sb strings.Builder
var push = func(in []string) { var push = func(in []string) {
sb.Grow((slen1 + 5) * len(in))
for _, path := range in { for _, path := range in {
sbuf += "</static/" + path + ">; rel=preload; as=script," sb.WriteString("</static/")
sb.WriteString(path)
sb.WriteString(">; rel=preload; as=script,")
} }
} }
push(header.Scripts) push(header.Scripts)
@ -36,15 +42,18 @@ func doPush(w http.ResponseWriter, header *c.Header) {
push(header.ScriptsAsync) push(header.ScriptsAsync)
if len(header.Stylesheets) > 0 { if len(header.Stylesheets) > 0 {
sb.Grow((slen2 + 6) * len(header.Stylesheets))
for _, path := range header.Stylesheets { for _, path := range header.Stylesheets {
sbuf += "</static/" + path + ">; rel=preload; as=style," sb.WriteString("</static/")
sb.WriteString(path)
sb.WriteString(">; rel=preload; as=style,")
} }
} }
// TODO: Push avatars? // TODO: Push avatars?
if len(sbuf) > 0 { if sb.Len() > 0 {
sbuf = sbuf[:len(sbuf)-1] sbuf := sb.String()
w.Header().Set("Link", sbuf) w.Header().Set("Link", sbuf[:len(sbuf)-1])
} }
} else if !c.Config.DisableServerPush { } else if !c.Config.DisableServerPush {
//fmt.Println("push enabled") //fmt.Println("push enabled")