Skip to content

Commit 6810ff6

Browse files
Googlertwifkak
authored andcommitted
Amp Packager SSR: Inject a loading=lazy img for every amp-img
97% (and growing) of Chrome browsers that support SXG also support loading=lazy. We still prioritize (via preload and loading=eager img) hero images. Requires transforming with Version 5. Re: #465 PiperOrigin-RevId: 336760832
1 parent c0967b3 commit 6810ff6

File tree

2 files changed

+66
-5
lines changed

2 files changed

+66
-5
lines changed

transformer/transformers/preloadimage.go

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,11 @@ func PreloadImage(e *Context) error {
6464
}
6565
}
6666

67+
// Finally, inject a loading=lazy img for all remaining amp-img elements.
68+
if e.Version >= 5 {
69+
lazyLoadRemainingAmpImgs(body)
70+
}
71+
6772
return nil
6873
}
6974

@@ -73,9 +78,8 @@ func prioritizeHeroImage(e *Context, heroImage HeroImage) {
7378
}
7479

7580
if ampImg := heroImage.ampImg; ampImg != nil {
76-
img := buildImg(ampImg)
81+
ampImg.AppendChild(buildImg(ampImg))
7782
htmlnode.SetAttribute(ampImg, "", "i-amphtml-ssr", "")
78-
ampImg.AppendChild(img)
7983
}
8084
}
8185

@@ -226,3 +230,23 @@ func srcsetToMediaQueries(srcset string) ([]mediaQuerySource, bool) {
226230
}
227231
return medias, true
228232
}
233+
234+
func lazyLoadRemainingAmpImgs(n *html.Node) {
235+
for n != nil {
236+
if n.Data == "amp-img" {
237+
// If the amp-img already has the ssr attribute, then it's a hero image with an already injected img.
238+
if !htmlnode.HasAttribute(n, "", "i-amphtml-ssr") {
239+
img := buildImg(n)
240+
htmlnode.SetAttribute(img, "", "loading", "lazy")
241+
n.AppendChild(img)
242+
htmlnode.SetAttribute(n, "", "i-amphtml-ssr", "")
243+
}
244+
245+
n = htmlnode.NextSkippingChildren(n)
246+
} else if n.Data == "template" {
247+
n = htmlnode.NextSkippingChildren(n)
248+
} else {
249+
n = htmlnode.Next(n)
250+
}
251+
}
252+
}

transformer/transformers/preloadimage_test.go

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import (
2626
"github.com/kylelemons/godebug/diff"
2727
)
2828

29-
func transformAndOutput(input string) (string, error) {
29+
func transformAndOutput(input string, version int64) (string, error) {
3030
inputDoc, err := html.Parse(strings.NewReader(input))
3131
if err != nil {
3232
return "", err
@@ -42,6 +42,7 @@ func transformAndOutput(input string) (string, error) {
4242
DOM: inputDOM,
4343
BaseURL: baseURL,
4444
DocumentURL: documentURL,
45+
Version: version,
4546
}
4647
transformers.PreloadImage(context)
4748
var output strings.Builder
@@ -320,10 +321,32 @@ var testcaseDataHero = []struct {
320321
},
321322
}
322323

324+
var testLazyLoadImg = []struct {
325+
testcaseName string
326+
input string
327+
expected string
328+
}{
329+
{
330+
"data-hero leftover",
331+
`<html><head></head><body><amp-img data-hero width="500" height="400" src="https://example.com/foo.png"></amp-img><amp-img width="500" height="400" src="https://example.com/bar.png"></amp-img></body></html>`,
332+
`<html><head><link rel="preload" as="image" href="https://example.com/foo.png"/></head><body><amp-img data-hero="" width="500" height="400" src="https://example.com/foo.png" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" src="https://example.com/foo.png"/></amp-img><amp-img width="500" height="400" src="https://example.com/bar.png" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" src="https://example.com/bar.png" loading="lazy"/></amp-img></body></html>`,
333+
},
334+
{
335+
"inferred-size leftover",
336+
`<html><head></head><body><amp-img width="500" height="400" src="https://example.com/foo.png"></amp-img><amp-img width="100" height="100" src="https://example.com/bar.png"></amp-img></body></html>`,
337+
`<html><head><link rel="preload" as="image" href="https://example.com/foo.png"/></head><body><amp-img width="500" height="400" src="https://example.com/foo.png" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" src="https://example.com/foo.png"/></amp-img><amp-img width="100" height="100" src="https://example.com/bar.png" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" src="https://example.com/bar.png" loading="lazy"/></amp-img></body></html>`,
338+
},
339+
{
340+
"no transformed images",
341+
`<html><head></head><body><amp-img width="100" height="100" src="https://example.com/foo.png"></amp-img></body></html>`,
342+
`<html><head></head><body><amp-img width="100" height="100" src="https://example.com/foo.png" i-amphtml-ssr=""><img class="i-amphtml-fill-content i-amphtml-replaced-content" decoding="async" src="https://example.com/foo.png" loading="lazy"/></amp-img></body></html>`,
343+
},
344+
}
345+
323346
func TestInferSizeCases(t *testing.T) {
324347
for _, tt := range testcaseInferSize {
325348
t.Run(tt.testcaseName, func(t *testing.T) {
326-
output, err := transformAndOutput(strings.TrimSpace(tt.input))
349+
output, err := transformAndOutput(strings.TrimSpace(tt.input), 0)
327350
if err != nil {
328351
t.Fatalf("Unexpected error %q", err)
329352
}
@@ -337,7 +360,21 @@ func TestInferSizeCases(t *testing.T) {
337360
func TestDataHeroCases(t *testing.T) {
338361
for _, tt := range testcaseDataHero {
339362
t.Run(tt.testcaseName, func(t *testing.T) {
340-
output, err := transformAndOutput(strings.TrimSpace(tt.input))
363+
output, err := transformAndOutput(strings.TrimSpace(tt.input), 0)
364+
if err != nil {
365+
t.Fatalf("Unexpected error %q", err)
366+
}
367+
if diff := diff.Diff(strings.TrimSpace(tt.expected), output); diff != "" {
368+
t.Errorf("PreloadImage transformer produced unexpected output:\n%s", diff)
369+
}
370+
})
371+
}
372+
}
373+
374+
func TestLazyLoadCases(t *testing.T) {
375+
for _, tt := range testLazyLoadImg {
376+
t.Run(tt.testcaseName, func(t *testing.T) {
377+
output, err := transformAndOutput(strings.TrimSpace(tt.input), 5)
341378
if err != nil {
342379
t.Fatalf("Unexpected error %q", err)
343380
}

0 commit comments

Comments
 (0)