Skip to content

Commit 62f0e69

Browse files
Support lazy loading
1 parent ddf8a39 commit 62f0e69

File tree

5 files changed

+61
-6
lines changed

5 files changed

+61
-6
lines changed

README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,20 @@ Default: `[]`
6868
Description: *list of extension for which the transformation will be ignored*
6969
Example: `extensionIgnore: ['svg']` will ignore transformation for images with the `svg` extension
7070

71+
#### `lazySrcset`
72+
73+
Type: `String`
74+
Default: `data-srcset`
75+
Description: *The attribute used for lazy webp loading. It will be set on created `<source>` to later be processed by external lazy loading library.*
76+
Example: `lazySrcset: 'my-srcset'` will set `my-srcset` attribute on `<source>`
77+
78+
#### `lazySrc`
79+
80+
Type: `String`
81+
Default: `data-src`
82+
Description: *The attribute used for lazy webp loading. The original `<img>` may not contain `src` at all, but instead some custom lazy-loading attribute. Or it may contain just a placeholder image inside `src` which shouldn't be used for webp conversion. `lazySrc` will define a custom attribute name to look at when processing your lazy loaded images. Note that `lazySrcset` is still needed even if `<img>` has only `lazySrc` defined, because `srcset` is the mechanism for defining a source file for the `<source>`. See `lazySrcset` option description.*
83+
Example: `lazySrc: 'my-src'` will convert an image inside `my-src` attribute, instead of regular `src`.
84+
7185
### License [MIT](LICENSE)
7286

7387
[npm]: https://img.shields.io/npm/v/posthtml-webp.svg

lib/index.js

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,21 @@ module.exports = function (options) {
1717
options.replaceExtension = false
1818
}
1919

20+
if (options.lazySrc === undefined) {
21+
options.lazySrc = 'data-src'
22+
}
23+
24+
if (options.lazySrcset === undefined) {
25+
options.lazySrcset = 'data-srcset'
26+
}
27+
2028
return function posthtmlWebp (tree) {
2129
tree.match([{ tag: 'img' }, { tag: 'amp-img' }], function (imgNode) {
2230
if (imgNode.skip) return imgNode
2331
var classes = (imgNode.attrs && imgNode.attrs.class && imgNode.attrs.class.split(' ')) || []
24-
var extension = imgNode.attrs.src.split('.').pop()
32+
// Extract extension from lazy loading attribute, because it always contains the right image. (`src` can contain "preview")
33+
// Use `src` if there are no lazy loading attributes.
34+
var extension = (imgNode.attrs[options.lazySrc] || imgNode.attrs[options.lazySrcset] || imgNode.attrs.src || imgNode.attrs.srcset).split('.').pop().split(/\s+/)[0]
2535
var isIgnoredByClass = options.classIgnore.filter(className => classes.includes(className)).length > 0
2636
var isIgnoredByExtension = options.extensionIgnore.filter(fileExtension => fileExtension === extension).length > 0
2737
var isIgnore = isIgnoredByClass || isIgnoredByExtension
@@ -77,7 +87,7 @@ function getAmpPicture (imgNode, options) {
7787
function getPicture (imgNode, options) {
7888
imgNode.skip = true
7989
// set <source> `srcset` to <img> `srcset`, if present; otherwise — use <img> `src`
80-
var srcset = (imgNode.attrs.srcset || imgNode.attrs.src)
90+
var srcset = (imgNode.attrs.srcset || imgNode.attrs[options.lazySrcset] || imgNode.attrs[options.lazySrc] || imgNode.attrs.src)
8191
.split(',')
8292
.filter(Boolean)
8393
.map(value => {
@@ -89,15 +99,18 @@ function getPicture (imgNode, options) {
8999
})
90100
.join(', ')
91101

102+
var sourceAttrs = {
103+
type: 'image/webp'
104+
}
105+
106+
sourceAttrs[imgNode.attrs[options.lazySrcset] || imgNode.attrs[options.lazySrc] ? options.lazySrcset : 'srcset'] = srcset
107+
92108
return {
93109
tag: 'picture',
94110
content: [
95111
{
96112
tag: 'source',
97-
attrs: {
98-
type: 'image/webp',
99-
srcset
100-
}
113+
attrs: sourceAttrs
101114
},
102115
imgNode
103116
]

test/fixtures/lazy.expected.html

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<!doctype html>
2+
<html>
3+
<body>
4+
<picture><source type="image/webp" data-srcset="photo.webp"><img data-src="photo.jpg"></picture>
5+
<picture><source type="image/webp" data-srcset="photo.webp"><img data-src="photo.jpg" src="low-quality-preview.jpg"></picture>
6+
<picture><source type="image/webp" data-srcset="photo-lg.webp 1000w, photo-md.webp 500w, photo-sm.webp 250w"><img data-srcset="photo-lg.jpg 1000w, photo-md.jpg 500w, photo-sm.jpg 250w"></picture>
7+
<picture><source type="image/webp" data-srcset="photo-lg.webp 1000w, photo-md.webp 500w, photo-sm.webp 250w"><img data-srcset="photo-lg.jpg 1000w, photo-md.jpg 500w, photo-sm.jpg 250w" src="low-quality-preview.jpg"></picture>
8+
<picture><source type="image/webp" data-srcset="photo-lg.webp 1000w, photo-md.webp 500w, photo-sm.webp 250w"><img data-srcset="photo-lg.jpg 1000w, photo-md.jpg 500w, photo-sm.jpg 250w" data-src="photo.jpg"></picture>
9+
<picture><source type="image/webp" data-srcset="photo-lg.webp 1000w, photo-md.webp 500w, photo-sm.webp 250w"><img data-srcset="photo-lg.jpg 1000w, photo-md.jpg 500w, photo-sm.jpg 250w" data-src="photo.jpg" src="low-quality-preview.jpg"></picture>
10+
</body>
11+
</html>

test/fixtures/lazy.html

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<!doctype html>
2+
<html>
3+
<body>
4+
<img data-src="photo.jpg">
5+
<img data-src="photo.jpg" src="low-quality-preview.jpg">
6+
<img data-srcset="photo-lg.jpg 1000w, photo-md.jpg 500w, photo-sm.jpg 250w">
7+
<img data-srcset="photo-lg.jpg 1000w, photo-md.jpg 500w, photo-sm.jpg 250w" src="low-quality-preview.jpg">
8+
<img data-srcset="photo-lg.jpg 1000w, photo-md.jpg 500w, photo-sm.jpg 250w" data-src="photo.jpg">
9+
<img data-srcset="photo-lg.jpg 1000w, photo-md.jpg 500w, photo-sm.jpg 250w" data-src="photo.jpg" src="low-quality-preview.jpg">
10+
</body>
11+
</html>

test/test.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@ test('Extension ignore', (t) => {
4545
})
4646
})
4747

48+
test('Lazy attributes', (t) => {
49+
return compare(t, 'lazy', {
50+
replaceExtension: true
51+
})
52+
})
53+
4854
function compare (t, name, options) {
4955
const html = readFileSync(path.join(fixtures, `${name}.html`), 'utf8')
5056
const expected = readFileSync(path.join(fixtures, `${name}.expected.html`), 'utf8')

0 commit comments

Comments
 (0)