图片懒加载从简单到复杂 的笔记

简单实现

当页面加载时先加载一个尺寸很小的占位图片(1kb以下),然后再通过js选择性的去加载真正的图片。

  1. <img src="placeholder.jpg" data-src="real_image.jpg" />
  1. img[data-src] {
  2. filter: blur(0.2em);
  3. }
  4. img {
  5. filter: blur(0em);
  6. transition: filter 0.5s;
  7. }
  1. (function lazyLoad(){
  2. const imageToLazy = document.querySelectorAll('img[data-src]');
  3. const loadImage = function (image) {
  4. image.setAttribute('src', image.getAttribute('data-src'));
  5. image.addEventListener('load', function() {
  6. image.removeAttribute("data-src");
  7. })
  8. }
  9. imageToLazy.forEach(function(image){
  10. loadImage(image);
  11. })
  12. })()

进阶实现–滚动加载

当图片出现在用户视窗中再进行加载(Intersection Observer)。

  1. (function lazyLoad(){
  2. const imageToLazy = document.querySelectorAll('img[data-src]');
  3. const loadImage = function (image) {
  4. image.setAttribute('src', image.getAttribute('data-src'));
  5. image.addEventListener('load', function() {
  6. image.removeAttribute("data-src");
  7. })
  8. }
  9. const intersectionObserver = new IntersectionObserver(function(items, observer) {
  10. items.forEach(function(item) {
  11. if(item.isIntersecting) {
  12. loadImage(item.target);
  13. observer.unobserve(item.target);
  14. }
  15. });
  16. });
  17. imageToLazy.forEach(function(image){
  18. intersectionObserver.observe(image);
  19. })
  20. })()

选择合适的 Placeholder 图片

  • 图片尺寸已知:可以自己裁剪对应尺寸的图片或使用 http://placeholder.com/ 之类的服务来获取 placeholder 图片
  • 图片尺寸未知:一般需要先生成对应图片的 thumbnail,然后使用该 thumbnail 作为 placeholder 图片;可以调用 imagemagick 或者调用一些在线的图片分割服务(比如 七牛

    懒加载时防止布局抖动

    在图片懒加载时,由于图片的尺寸不定,浏览器难以计算需要给图片预留出的位置。所以当图片加载完成后会出现网页布局的抖动。
    解决方法:采用 aspect ratio boxes(高宽比)来制作一个占位用的元素,padding-bottom: (height / width * 100)% 留出位置。
    1. <div class="lazy-load__container feature">
    2. <img src="placeholder.jpg" data-src="real.jpg" />
    3. </div>
    ```css .lazy-load__container{ position: relative; display: block; height: 0; }

.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 懒加载图片

  1. 使用 aspect ratio box 创建占位元素。
  2. 在 html 解析时只加载一个小尺寸的图片,并且添加 blur 效果。
  3. 最后使用 js 选择性的加载真实图片。

点击查看【codepen】