延迟加载图片的四种方法

480 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第3天,点击查看活动详情

图片是网络上最受欢迎的内容类型之一,网站引用大小不一的图片,网页加载时间很容易成为一个不容忽视的问题。本文将介绍四种延迟加载图片的方法,您可以将这些方法应用到您的优化上,以改善您网站是的用户体验。

原生的延迟加载

imgiframe标签原生延迟加载方法非常简单,只需要在标签上加上loading="lazy"即可:

    <img src="myimage.jpg" loading="lazy" alt="..." />
    <iframe src="content.html" loading="lazy"></iframe>

没有额外的JavaScript代码、没有src属性值的变更,只是普通的HTML代码。loading属性允许浏览器延迟加载不在视口的图片和iframe,直到用户滚动到它们附近。loading支持三个值

  • lazy:延迟加载,直到满足某些条件
  • eager:立即加载指定内容(浏览器默认为改属性)
  • auto:浏览器自由判断是否延迟加载

目前大多数浏览器已经对该属性提供了良好的支持,如果考虑兼容性,可参考其它延迟加载方案。

使用Intersection Observer API进行延迟加载

Intersection Observer API提供了一种异步检测目标节点和父节点或viewport相交情况变化的方法。换个说法,就是异步监视两个元素间的交集。具体实现图片延迟加载方式:

首先,给图片img设置一个自定义属性data-src来接收图片的实际url地址:

    <img data-src="image.jpg" alt="test image">

请注意图片路径需要设置在data-src中,而不是src中,因为直接使用src意味着图片会立即加载。css样式方面,我们最好给img设置一个高度提前占位,例如:

    img {
      min-height: 100px;
      /* more styles here */
    }

然后在JavaScript中创建一个config对象并将其注册到一个intersectionObserver实例中:

const config = {
  rootMargin: '0px 0px 50px 0px',
  threshold: 0
};

let observer = new IntersectionObserver(function(entries, self) {
  entries.forEach(entry => {
    // 监听相交的图像
    if(entry.isIntersecting) {
      // preloadImage为自定义方法:将img 的 data-src 赋值给 src
      preloadImage(entry.target);
      // 处理完毕,停止监听相交
      self.unobserve(entry.target);
    }
  });
}, config);
function preloadImage (img) {
    img.setAttribute('src', img.getAttribute('data-src'))
}

最后,我们只需遍历所有img并将他们添加到此intersectionObserver实例中:

const imgs = document.querySelectorAll('[data-src]');
imgs.forEach(img => {
  observer.observe(img);
});

至此intersectionObserver图片延迟加载的方案就完成了,在兼容性方面并不是所有的浏览器都支持的,幸运的是,我们可以使用polyfill

使用Lozad.js进行延迟加载

Lozad.js是一个高性能、轻量级和可配置的纯JavaScript懒加载器,不需要其它依赖。您可以使用它来延迟加载图片、视频、iframe等,它使用的是Intersection Observer API

使用方式,可以使用npm/Yarn进行引入:

npm install --save lozad

yarn add lozad

或者通过CDN的方式在HTML中直接引入:

<script src="https://cdn.jsdelivr.net/npm/lozad/dist/lozad.min.js"></script>

使用方式是给img添加lozad类,并把资源地址放在data-src中,例如:

<img class="lozad" data-src="img.jpg">

最后在JavaScript中实例化一下即可:

const observer = lozad();
observer.observe();

更多资料,可参考Lozad GitHub

Yall.js

Yall是一个用于图片、视频和iframe延迟加载脚本,更具体地说,它使用Intersection Observer API,并在必要时巧妙地回退到传统事件的处理程序技术。

在使用Yall时,需要按照下面方式进行初始化:

<script src="yall.min.js"></script>
<script>
  document.addEventListener("DOMContentLoaded", yall);
</script>

然后给对应的标签添加标记属性:

<img class="lazy" src="placeholder.jpg" data-src="image-to-lazy-load.jpg" alt="Alternative text to describe image.">

使用注意事项:

  • 为元素添加lazy
  • 元素的src是一个占位符图像,并不是实际资源地址
  • 要延迟加载是图片资源地址设置在data-src属性内

更详细可查看GitHub