Commit 846c4cbe36

846c4cbe361c4787cb79c913487ec897243822e6

parent: 0d06714a92

Verified · cmc

cmc <hello@cleberg.net> · 2026-09-26 18:48 UTC

Preload neighbours via imagesrcset; use file names as alt text

Preloads for the previous and next photo now carry the same srcset and
sizes as the photo itself, so the browser preloads the file it will use.
Album tiles and the photo page use the file name as alt text.

Closes #2
Closes #6

Layout: unified · split

internal/web/server_test.go +2 −2
@@ -95,8 +95,8 @@ func TestPages(t *testing.T) {
95 reject []string 95 reject []string
96 }{ 96 }{
97 {"/", 200, []string{`href="/tokyo/"`, `data-ar="1.5000"`, "Tokyo", "2025", `href="/info/"`}, nil}, 97 {"/", 200, []string{`href="/tokyo/"`, `data-ar="1.5000"`, "Tokyo", "2025", `href="/info/"`}, nil},
98 {"/tokyo/", 200, []string{`href="/tokyo/a.jpg/"`, `href="/tokyo/b.jpg/"`, `/img/tokyo/a.jpg/960.jpg?v=`, `480w`, `class="on"`}, nil}, 98 {"/tokyo/", 200, []string{`href="/tokyo/a.jpg/"`, `href="/tokyo/b.jpg/"`, `/img/tokyo/a.jpg/960.jpg?v=`, `480w`, `class="on"`, `alt="a.jpg"`}, []string{`alt=""`}},
99 {"/tokyo/a.jpg/", 200, []string{"a.jpg — 1 / 2", "X-T5 · f/2 · 1/125 · ISO 1600 · 2025-03-14", `rel="next" href="/tokyo/b.jpg/"`, `id="up" href="/tokyo/"`}, []string{`rel="prev"`}}, 99 {"/tokyo/a.jpg/", 200, []string{"a.jpg — 1 / 2", "X-T5 · f/2 · 1/125 · ISO 1600 · 2025-03-14", `rel="next" href="/tokyo/b.jpg/"`, `id="up" href="/tokyo/"`, `alt="a.jpg"`, `rel="preload" as="image" imagesrcset="/img/tokyo/b.jpg/480.jpg`, `imagesizes="100vw"`}, []string{`rel="prev"`, `alt=""`}},
100 {"/tokyo/b.jpg/", 200, []string{`rel="prev" href="/tokyo/a.jpg/"`, "2 / 2"}, []string{`rel="next"`}}, 100 {"/tokyo/b.jpg/", 200, []string{`rel="prev" href="/tokyo/a.jpg/"`, "2 / 2"}, []string{`rel="next"`}},
101 {"/info/", 200, []string{"<em>there</em>"}, nil}, 101 {"/info/", 200, []string{"<em>there</em>"}, nil},
102 {"/nope/", 404, []string{"404"}, nil}, 102 {"/nope/", 404, []string{"404"}, nil},
internal/web/templates/album.html +1 −1
@@ -8,7 +8,7 @@
8<div class="rows"> 8<div class="rows">
9{{- range .Album.Items}} 9{{- range .Album.Items}}
10 <a class="tile" href="{{photoURL .}}" data-ar="{{ar .}}" style="--ar:{{ar .}}"> 10 <a class="tile" href="{{photoURL .}}" data-ar="{{ar .}}" style="--ar:{{ar .}}">
11 <img src="{{imgURL . 960}}" srcset="{{srcset .}}" sizes="(max-width: 600px) 100vw, 33vw" width="{{.Meta.Width}}" height="{{.Meta.Height}}" loading="lazy" alt=""> 11 <img src="{{imgURL . 960}}" srcset="{{srcset .}}" sizes="(max-width: 600px) 100vw, 33vw" width="{{.Meta.Width}}" height="{{.Meta.Height}}" loading="lazy" alt="{{.Name}}">
12 </a> 12 </a>
13{{- end}} 13{{- end}}
14</div> 14</div>
internal/web/templates/photo.html +3 −3
@@ -3,7 +3,7 @@
3{{define "content"}} 3{{define "content"}}
4<figure class="stage"> 4<figure class="stage">
5 {{with .Prev}}<a class="prev" rel="prev" href="{{photoURL .}}" aria-label="Previous">‹</a>{{end}} 5 {{with .Prev}}<a class="prev" rel="prev" href="{{photoURL .}}" aria-label="Previous">‹</a>{{end}}
6 <img src="{{imgURL .Item 1600}}" srcset="{{srcset .Item}}" sizes="100vw" width="{{.Item.Meta.Width}}" height="{{.Item.Meta.Height}}" alt=""> 6 <img src="{{imgURL .Item 1600}}" srcset="{{srcset .Item}}" sizes="100vw" width="{{.Item.Meta.Width}}" height="{{.Item.Meta.Height}}" alt="{{.Item.Name}}">
7 {{with .Next}}<a class="next" rel="next" href="{{photoURL .}}" aria-label="Next">›</a>{{end}} 7 {{with .Next}}<a class="next" rel="next" href="{{photoURL .}}" aria-label="Next">›</a>{{end}}
8</figure> 8</figure>
9<footer class="meta"> 9<footer class="meta">
@@ -11,6 +11,6 @@
11 <span>{{exif .Item}}</span> 11 <span>{{exif .Item}}</span>
12</footer> 12</footer>
13<a id="up" href="{{albumURL .Album}}" hidden></a> 13<a id="up" href="{{albumURL .Album}}" hidden></a>
14{{with .Prev}}<link rel="preload" as="image" href="{{imgURL . 1600}}">{{end}} 14{{with .Prev}}<link rel="preload" as="image" imagesrcset="{{srcset .}}" imagesizes="100vw">{{end}}
15{{with .Next}}<link rel="preload" as="image" href="{{imgURL . 1600}}">{{end}} 15{{with .Next}}<link rel="preload" as="image" imagesrcset="{{srcset .}}" imagesizes="100vw">{{end}}
16{{end}} 16{{end}}