图片懒加载从简单到复杂 的笔记
简单实现
当页面加载时先加载一个尺寸很小的占位图片(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 选择性的加载真实图片。
 
