Skip to content

Commit

Permalink
perf: add rel=preload tag for images
Browse files Browse the repository at this point in the history
  • Loading branch information
macrat committed Jan 6, 2024
1 parent 0821276 commit 4f5eeeb
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 11 deletions.
34 changes: 31 additions & 3 deletions builder/article.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,31 @@ import (
"gopkg.in/yaml.v3"
)

// ResourceInfo is information for preloading resources.
type ResourceInfo struct {
Type string
URL string
}

type ResourceList []ResourceInfo

func (l ResourceList) Has(r ResourceInfo) bool {
for _, x := range l {
if x.Type == r.Type && x.URL == r.URL {
return true
}
}
return false
}

func (l *ResourceList) Add(xs ...ResourceInfo) {
for _, x := range xs {
if !l.Has(x) {
*l = append(*l, x)
}
}
}

type Article struct {
name string `yaml:"-"`
source Source `yaml:"-"`
Expand All @@ -30,8 +55,9 @@ type Article struct {
BreadCrumb []BreadCrumbItem `yaml:"breadcrumb"`
Layout string `yaml:"layout"`

Markdown []byte `yaml:"-"`
Content template.HTML `yaml:"-"`
Resources []ResourceInfo `yaml:"-"`
Markdown []byte `yaml:"-"`
Content template.HTML `yaml:"-"`
}

func (a Article) Name() string {
Expand Down Expand Up @@ -101,9 +127,11 @@ func (l *ArticleLoader) Load(externalPath string, raw []byte) (Article, error) {
}

var buf strings.Builder
if err := l.md.Convert(&buf, article.Markdown); err != nil {
resources, err := l.md.Convert(&buf, article.Markdown)
if err != nil {
return Article{}, err
}
article.Resources = resources
article.Content = template.HTML(buf.String())

return article, nil
Expand Down
26 changes: 18 additions & 8 deletions builder/markdown.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,40 +58,44 @@ func NewMarkdown() *Markdown {
}
}

func (c *Markdown) Convert(w io.Writer, source []byte) error {
func (c *Markdown) Convert(w io.Writer, source []byte) (ResourceList, error) {
var buf bytes.Buffer

code := NewCodeRenderer(c.lexers)
image := &ImageRenderer{}
md := markdown.NewConverter(markdown.WithNodeRenderers(
code,
HeadingRenderer{},
ImageRenderer{},
image,
TableRenderer{},
LinkRenderer{},
))

if err := md.Convert(&buf, source); err != nil {
return err
return nil, err
}

if code.Count > 0 {
if _, err := w.Write([]byte("<style>")); err != nil {
return err
return nil, err
}

if err := code.WriteStyleSheet(w); err != nil {
return err
return nil, err
}

if _, err := w.Write([]byte("</style>")); err != nil {
return err
return nil, err
}
}

code.Count = 0

var resources ResourceList
resources.Add(image.Resources...)

_, err := buf.WriteTo(w)
return err
return resources, err
}

// CodeRenderer is a renderer for fenced code blocks with highlighting.
Expand Down Expand Up @@ -243,6 +247,7 @@ func (r HeadingRenderer) Render(w markdown.BufWriter, source []byte, node ast.No

// ImageRenderer renders images with width and height.
type ImageRenderer struct {
Resources ResourceList
}

func (r ImageRenderer) Priority() int {
Expand All @@ -253,7 +258,7 @@ func (r ImageRenderer) Kind() ast.NodeKind {
return ast.KindImage
}

func (r ImageRenderer) Render(w markdown.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) {
func (r *ImageRenderer) Render(w markdown.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) {
if !entering {
fmt.Fprintf(w, "</img>")
return ast.WalkContinue, nil
Expand All @@ -272,6 +277,11 @@ func (r ImageRenderer) Render(w markdown.BufWriter, source []byte, node ast.Node
sizes[2],
)

r.Resources.Add(ResourceInfo{
Type: "image",
URL: string(image.Destination),
})

return ast.WalkSkipChildren, err
} else {
return ast.WalkStop, fmt.Errorf("All images needs size as its title but got %q.", image.Title)
Expand Down
3 changes: 3 additions & 0 deletions templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
<html lang="ja">
<head>
<meta charset="utf-8">

{{block "early-head" .}}{{end}}

<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{block "title" .}}Blanktar{{end}}</title>
<link rel="icon" href="/favicon.svg">
Expand Down
8 changes: 8 additions & 0 deletions templates/blog/post.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
{{define "title"}}{{.Title}} - Blanktar{{end}}

{{define "early-head"}}
{{if .Resources}}
{{range .Resources}}
<link rel="preload" href="{{.URL}}" as="{{.Type}}">
{{end}}
{{end}}
{{end}}

{{define "head"}}
<meta property="og:image" content="https://blanktar.jp{{if .Image}}{{index .Image 0}}{{else}}/images/blanktar.png{{end}}">

Expand Down
8 changes: 8 additions & 0 deletions templates/default.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
{{define "title"}}{{.Title}} - Blanktar{{end}}

{{define "early-head"}}
{{if .Resources}}
{{range .Resources}}
<link rel="preload" href="{{.URL}}" as="{{.Type}}">
{{end}}
{{end}}
{{end}}

{{define "head"}}
<meta property="og:image" content="https://blanktar.jp{{if .Image}}{{index .Image 0}}{{else}}/images/blanktar.jpg{{end}}">

Expand Down

0 comments on commit 4f5eeeb

Please sign in to comment.