Skip to content

图片懒加载

懒加载,顾名思义,在当前网页,滑动页面到能看到图片的时候再加载图片

故问题拆分成两个:

1 如何判断图片出现在了当前视口 (即如何判断我们能够看到图片)

2 如何控制图片的加载

方案一:位置计算 + 滚动事件 (Scroll) + DataSet API

如何判断图片出现在了当前视口

clientTop,offsetTop,clientHeight 以及 scrollTop 各种关于图片的高度作比对

这些高度都代表了什么意思?

这我以前有可能是知道的,那时候我比较单纯,喜欢死磕。我现在想通了,背不过的东西就不要背了

所以它有一个问题:复杂琐碎不好理解!

仅仅知道它静态的高度还不够,我们还需要知道动态的

如何动态?监听 window.scroll 事件

如何控制图片的加载

html
<img data-src="imgpath.jpg" />

首先设置一个临时 Data 属性 data-src,控制加载时使用 src 代替 data-src,可利用 DataSet API 实现

方案二:IntersectionObserver API + DataSet API

如何判断图片出现在了当前视口

IntersectionObserver API,一个能够监听元素是否到了当前视口的事件,一步到位!

事件回调的参数是 IntersectionObserverEntry (opens new window)的集合,代表关于是否在可见视口的一系列值

其中,entry.isIntersecting 代表目标元素可见

js
const observer = new IntersectionObserver((changes) => {
  // changes: 目标元素集合
  changes.forEach((change) => {
    // intersectionRatio
    if (change.isIntersecting) {
      const img = change.target;
      img.src = img.dataset.src;
      observer.unobserve(img);
    }
  });
});

observer.observe(img);

当然,IntersectionObserver 除了给图片做懒加载外,还可以对单页应用资源做预加载。

如在 next.js v9 中,会对视口内的资源做预加载

html
<Link href="/about">
  <a>关于山月</a>
</Link>

在react中可以利用ref实现: https://juejin.cn/post/6844903768966856717

方案三:LazyLoading 属性

浏览器觉得懒加载这事可以交给自己做,你们开发者加个属性就好了。实在是...!不过目前浏览器兼容性不太好,

html
<img src="shanyue.jpg" loading="lazy" />

苏ICP备2025160170号-1 | 前端进化之路 | Released under the MIT License.