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:
parent
42b9f27c45
commit
c84b0aa433
|
@ -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
|
||||||
|
|
|
@ -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 == "" {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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")
|
||||||
|
|
Loading…
Reference in New Issue