延迟加载图片元素
Lazyloading picture elements
我正在寻找有关如何最好地延迟加载图片元素的建议。我可能喜欢使用一个小的 jQuery 辅助函数来确定图片是否为 "on screen"。但是 srcset 的延迟获取,我现在不确定该怎么做。那么,有什么想法吗?
这是我正在使用的图片元素的示例。谢谢!
<picture alt="Random Celebrities" data-src="http://www.example.com/r/c_1,h_478,w_478/2015/03/19/random-celebrities-08-560x560.jpg">
<!--[if IE 9]><video style="display: none;"><![endif]-->
<source class='picture-source-1260' srcset='http://www.example.com/r/c_1,h_239,w_239/2015/03/19/random-celebrities-08-560x560.jpg, http://www.example.com/r/c_1,h_478,w_478/2015/03/19/random-celebrities-08-560x560.jpg 2x' media='(min-width: 1260px)'>
<source class='picture-source-960' srcset='http://www.example.com/r/c_1,h_180,w_180/2015/03/19/random-celebrities-08-560x560.jpg, http://www.example.com/r/c_1,h_360,w_360/2015/03/19/random-celebrities-08-560x560.jpg 2x' media='(min-width: 960px)'>
<source class='picture-source-760' srcset='http://www.example.com/r/c_1,h_150,w_150/2015/03/19/random-celebrities-08-560x560.jpg, http://www.example.com/r/c_1,h_300,w_300/2015/03/19/random-celebrities-08-560x560.jpg 2x' media='(min-width: 760px)'>
<source class='picture-source-450' srcset='http://www.example.com/r/c_1,h_210,w_210/2015/03/19/random-celebrities-08-560x560.jpg, http://www.example.com/r/c_1,h_420,w_420/2015/03/19/random-celebrities-08-560x560.jpg 2x' media='(min-width: 450px)'>
<source class='picture-source-320' srcset='http://www.example.com/r/c_1,h_160,w_160/2015/03/19/random-celebrities-08-560x560.jpg, http://www.example.com/r/c_1,h_320,w_320/2015/03/19/random-celebrities-08-560x560.jpg 2x'>
<!--[if IE 9]></video><![endif]-->
<noscript>
<img class="picture-img-noscript" src="http://www.example.com/r/c_1,h_160,w_160/2015/03/19/random-celebrities-08-560x560.jpg" alt="Random Celebrities" />
</noscript>
<img class="picture-img" srcset="http://www.example.com/r/c_1,h_160,w_160/2015/03/19/random-celebrities-08-560x560.jpg" alt="Random Celebrities" />
</picture>
使用lazysizes,它是一个用于正常和响应式图像(包括图片元素)的高性能延迟加载器。
你真的不需要插件,只要在你的图片标签上放一个class,去掉里面的"img"标签,然后把src放在srcset里面:
<picture class="lazy">
<source srcset='/images/image.jpg'/>
</picture>
然后在 javascript 加载 dom 后:
获取所有“.lazy”节点:
const lazyImages = document.querySelectorAll('.lazy');
像这样调用一个函数:
function lazyLoadImages() {
lazyImages.forEach((val,i) => {
let src = val.querySelector('source').getAttribute('srcset');
let image = new Image();
image.src = src;
val.append(image);
})
}
我在这里创建了一个带有解决方案的笔:
在 Chrome & Firefox、Safari 和 IE11 中测试(后者的后备)
<!-- Load images above the fold normally -->
<picture>
<source srcset="img/city-m.jpg" media="(max-width: 960px)">
<source srcset="img/city-l.jpg" media="(min-width: 961px)">
<img class="fade-in" src="img/city-l.jpg" alt="city"/>
</picture>
<picture>
<source srcset="img/forest-m.jpg" media="(max-width: 960px)">
<source srcset="img/forest-l.jpg" media="(min-width: 961px)">
<img class="fade-in" src="img/forest-l.jpg" alt="forest"/>
</picture>
<!-- Lazy load images below the fold -->
<picture class="lazy">
<source data-srcset="img/river-m.jpg" media="(max-width: 960px)">
<source data-srcset="img/river-l.jpg" media="(min-width: 961px)">
<img data-srcset="img/river-l.jpg" alt="river"/>
</picture>
<picture class="lazy">
<source data-srcset="img/desert-m.jpg" media="(max-width: 960px)">
<source data-srcset="img/desert-l.jpg" media="(min-width: 961px)">
<img data-srcset="img/desert-l.jpg" alt="desert"/>
</picture>
和 JS:
document.addEventListener("DOMContentLoaded", function(event) {
var lazyImages =[].slice.call(
document.querySelectorAll(".lazy > source")
)
if ("IntersectionObserver" in window) {
let lazyImageObserver =
new IntersectionObserver(function(entries, observer) {
entries.forEach(function(entry) {
if (entry.isIntersecting) {
let lazyImage = entry.target;
lazyImage.srcset = lazyImage.dataset.srcset;
lazyImage.nextElementSibling.srcset = lazyImage.dataset.srcset;
lazyImage.nextElementSibling.classList.add('fade-in');
lazyImage.parentElement.classList.remove("lazy");
lazyImageObserver.unobserve(lazyImage);
}
});
});
lazyImages.forEach(function(lazyImage) {
lazyImageObserver.observe(lazyImage);
});
} else {
// Not supported, load all images immediately
lazyImages.forEach(function(image){
image.nextElementSibling.src = image.nextElementSibling.dataset.srcset;
});
}
});
我正在寻找有关如何最好地延迟加载图片元素的建议。我可能喜欢使用一个小的 jQuery 辅助函数来确定图片是否为 "on screen"。但是 srcset 的延迟获取,我现在不确定该怎么做。那么,有什么想法吗?
这是我正在使用的图片元素的示例。谢谢!
<picture alt="Random Celebrities" data-src="http://www.example.com/r/c_1,h_478,w_478/2015/03/19/random-celebrities-08-560x560.jpg">
<!--[if IE 9]><video style="display: none;"><![endif]-->
<source class='picture-source-1260' srcset='http://www.example.com/r/c_1,h_239,w_239/2015/03/19/random-celebrities-08-560x560.jpg, http://www.example.com/r/c_1,h_478,w_478/2015/03/19/random-celebrities-08-560x560.jpg 2x' media='(min-width: 1260px)'>
<source class='picture-source-960' srcset='http://www.example.com/r/c_1,h_180,w_180/2015/03/19/random-celebrities-08-560x560.jpg, http://www.example.com/r/c_1,h_360,w_360/2015/03/19/random-celebrities-08-560x560.jpg 2x' media='(min-width: 960px)'>
<source class='picture-source-760' srcset='http://www.example.com/r/c_1,h_150,w_150/2015/03/19/random-celebrities-08-560x560.jpg, http://www.example.com/r/c_1,h_300,w_300/2015/03/19/random-celebrities-08-560x560.jpg 2x' media='(min-width: 760px)'>
<source class='picture-source-450' srcset='http://www.example.com/r/c_1,h_210,w_210/2015/03/19/random-celebrities-08-560x560.jpg, http://www.example.com/r/c_1,h_420,w_420/2015/03/19/random-celebrities-08-560x560.jpg 2x' media='(min-width: 450px)'>
<source class='picture-source-320' srcset='http://www.example.com/r/c_1,h_160,w_160/2015/03/19/random-celebrities-08-560x560.jpg, http://www.example.com/r/c_1,h_320,w_320/2015/03/19/random-celebrities-08-560x560.jpg 2x'>
<!--[if IE 9]></video><![endif]-->
<noscript>
<img class="picture-img-noscript" src="http://www.example.com/r/c_1,h_160,w_160/2015/03/19/random-celebrities-08-560x560.jpg" alt="Random Celebrities" />
</noscript>
<img class="picture-img" srcset="http://www.example.com/r/c_1,h_160,w_160/2015/03/19/random-celebrities-08-560x560.jpg" alt="Random Celebrities" />
</picture>
使用lazysizes,它是一个用于正常和响应式图像(包括图片元素)的高性能延迟加载器。
你真的不需要插件,只要在你的图片标签上放一个class,去掉里面的"img"标签,然后把src放在srcset里面:
<picture class="lazy">
<source srcset='/images/image.jpg'/>
</picture>
然后在 javascript 加载 dom 后:
获取所有“.lazy”节点:
const lazyImages = document.querySelectorAll('.lazy');
像这样调用一个函数:
function lazyLoadImages() {
lazyImages.forEach((val,i) => {
let src = val.querySelector('source').getAttribute('srcset');
let image = new Image();
image.src = src;
val.append(image);
})
}
我在这里创建了一个带有解决方案的笔:
在 Chrome & Firefox、Safari 和 IE11 中测试(后者的后备)
<!-- Load images above the fold normally -->
<picture>
<source srcset="img/city-m.jpg" media="(max-width: 960px)">
<source srcset="img/city-l.jpg" media="(min-width: 961px)">
<img class="fade-in" src="img/city-l.jpg" alt="city"/>
</picture>
<picture>
<source srcset="img/forest-m.jpg" media="(max-width: 960px)">
<source srcset="img/forest-l.jpg" media="(min-width: 961px)">
<img class="fade-in" src="img/forest-l.jpg" alt="forest"/>
</picture>
<!-- Lazy load images below the fold -->
<picture class="lazy">
<source data-srcset="img/river-m.jpg" media="(max-width: 960px)">
<source data-srcset="img/river-l.jpg" media="(min-width: 961px)">
<img data-srcset="img/river-l.jpg" alt="river"/>
</picture>
<picture class="lazy">
<source data-srcset="img/desert-m.jpg" media="(max-width: 960px)">
<source data-srcset="img/desert-l.jpg" media="(min-width: 961px)">
<img data-srcset="img/desert-l.jpg" alt="desert"/>
</picture>
和 JS:
document.addEventListener("DOMContentLoaded", function(event) {
var lazyImages =[].slice.call(
document.querySelectorAll(".lazy > source")
)
if ("IntersectionObserver" in window) {
let lazyImageObserver =
new IntersectionObserver(function(entries, observer) {
entries.forEach(function(entry) {
if (entry.isIntersecting) {
let lazyImage = entry.target;
lazyImage.srcset = lazyImage.dataset.srcset;
lazyImage.nextElementSibling.srcset = lazyImage.dataset.srcset;
lazyImage.nextElementSibling.classList.add('fade-in');
lazyImage.parentElement.classList.remove("lazy");
lazyImageObserver.unobserve(lazyImage);
}
});
});
lazyImages.forEach(function(lazyImage) {
lazyImageObserver.observe(lazyImage);
});
} else {
// Not supported, load all images immediately
lazyImages.forEach(function(image){
image.nextElementSibling.src = image.nextElementSibling.dataset.srcset;
});
}
});