From 7625cb131a85d4f3c45683251702fc0f0ff3f8c2 Mon Sep 17 00:00:00 2001 From: Alan Pearce Date: Wed, 24 Apr 2024 15:17:51 +0200 Subject: template: open files only once --- cmd/build/template.go | 42 +++++++++++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/cmd/build/template.go b/cmd/build/template.go index 5ea1912..b3576a2 100644 --- a/cmd/build/template.go +++ b/cmd/build/template.go @@ -8,6 +8,7 @@ import ( "net/url" "os" "strings" + "sync" "time" "website/internal/atom" "website/internal/config" @@ -20,16 +21,39 @@ import ( "golang.org/x/net/html" ) +var ( + assetsOnce sync.Once + css string + templates map[string]*os.File = make(map[string]*os.File) +) + +func loadTemplate(path string) (file *os.File, err error) { + if templates[path] == nil { + file, err = os.Open(path) + if err != nil { + return nil, err + } + templates[path] = file + } + file = templates[path] + return +} + func layout(filename string, config config.Config, pageTitle string) (*goquery.Document, error) { - html, err := os.Open(filename) + html, err := loadTemplate(filename) if err != nil { return nil, err } - defer html.Close() - css, err := os.ReadFile("templates/style.css") + defer html.Seek(0, io.SeekStart) + assetsOnce.Do(func() { + var bytes []byte + bytes, err = os.ReadFile("templates/style.css") + css = string(bytes) + }) if err != nil { return nil, err } + doc, err := goquery.NewDocumentFromReader(html) if err != nil { return nil, err @@ -178,11 +202,11 @@ func render404(config config.Config) (io.Reader, error) { } func renderFeed(title string, config config.Config, posts []Post, specific string) (io.Reader, error) { - reader, err := os.Open("templates/feed.xml") + reader, err := loadTemplate("templates/feed.xml") if err != nil { return nil, err } - defer reader.Close() + defer reader.Seek(0, io.SeekStart) doc, err := xmlquery.Parse(reader) feed := doc.SelectElement("feed") feed.SelectElement("title").FirstChild.Data = title @@ -230,11 +254,11 @@ func renderFeed(title string, config config.Config, posts []Post, specific strin } func renderFeedStyles() (io.Reader, error) { - reader, err := os.Open("templates/feed-styles.xsl") + reader, err := loadTemplate("templates/feed-styles.xsl") if err != nil { return nil, err } - defer reader.Close() + defer reader.Seek(0, io.SeekStart) nsMap := map[string]string{ "xsl": "http://www.w3.org/1999/XSL/Transform", "atom": "http://www.w3.org/2005/Atom", @@ -246,10 +270,6 @@ func renderFeedStyles() (io.Reader, error) { return nil, err } style := xmlquery.QuerySelector(doc, expr) - css, err := os.ReadFile("templates/style.css") - if err != nil { - return nil, err - } xmlquery.AddChild(style, &xmlquery.Node{ Type: xmlquery.TextNode, Data: string(css), -- cgit 1.4.1