图片懒加载从简单到复杂 的笔记
简单实现
当页面加载时先加载一个尺寸很小的占位图片(1kb以下),然后再通过js选择性的去加载真正的图片。
<img src="placeholder.jpg" data-src="real_image.jpg" />
img[data-src] {
filter: blur(0.2em);
}
img {
filter: blur(0em);
transition: filter 0.5s;
}
(function lazyLoad(){
const imageToLazy = document.querySelectorAll('img[data-src]');
const loadImage = function (image) {
image.setAttribute('src', image.getAttribute('data-src'));
image.addEventListener('load', function() {
image.removeAttribute("data-src");
})
}
imageToLazy.forEach(function(image){
loadImage(image);
})
})()
进阶实现–滚动加载
当图片出现在用户视窗中再进行加载(Intersection Observer)。
(function lazyLoad(){
const imageToLazy = document.querySelectorAll('img[data-src]');
const loadImage = function (image) {
image.setAttribute('src', image.getAttribute('data-src'));
image.addEventListener('load', function() {
image.removeAttribute("data-src");
})
}
const intersectionObserver = new IntersectionObserver(function(items, observer) {
items.forEach(function(item) {
if(item.isIntersecting) {
loadImage(item.target);
observer.unobserve(item.target);
}
});
});
imageToLazy.forEach(function(image){
intersectionObserver.observe(image);
})
})()
选择合适的 Placeholder 图片
- 图片尺寸已知:可以自己裁剪对应尺寸的图片或使用 http://placeholder.com/ 之类的服务来获取 placeholder 图片
- 图片尺寸未知:一般需要先生成对应图片的 thumbnail,然后使用该 thumbnail 作为 placeholder 图片;可以调用 imagemagick 或者调用一些在线的图片分割服务(比如 七牛)
懒加载时防止布局抖动
在图片懒加载时,由于图片的尺寸不定,浏览器难以计算需要给图片预留出的位置。所以当图片加载完成后会出现网页布局的抖动。
解决方法:采用 aspect ratio boxes(高宽比)来制作一个占位用的元素,padding-bottom: (height / width * 100)%
留出位置。
```css .lazy-load__container{ position: relative; display: block; height: 0; }<div class="lazy-load__container feature">
<img src="placeholder.jpg" data-src="real.jpg" />
</div>
.lazy-load__container.feature { // feature image 的高宽比设置成42.8% // 对于其他图片 比如 post图片,高宽比可能会不同,可以使用其他css class去设置 padding-bottom: 42.8%; }
.lazy-load__container img { position: absolute; top:0; left:0; height: 100%; width: 100%; } ```
例子:Medium 懒加载图片
- 使用 aspect ratio box 创建占位元素。
- 在 html 解析时只加载一个小尺寸的图片,并且添加 blur 效果。
- 最后使用 js 选择性的加载真实图片。