实现图片懒加载的几种方法

[复制链接]
查看1570 | 回复0 | 2021-2-27 08:52 | 显示全部楼层 |阅读模式
懒加载就是延时加载,即当对象需要用到的时候再去加载。本文就来为大家介绍几种实现图片懒加载的方法,希望对大家有一定的帮助。
懒加载,顾名思义,在当前网页,滑动页面到能看到图片的时候再加载图片
故问题拆分成两个:
  • 如何判断图片出现在了当前视口 (即如何判断我们能够看到图片)
  • 如何控制图片的加载

方案一
如何判断图片出现在了当前视口
clientTop,offsetTop,clientHeight 以及 scrollTop 各种关于图片的高度作比对
这些高度都代表了什么意思?
这我以前有可能是知道的,那时候我比较单纯,喜欢死磕。我现在想通了,背不过的东西就不要背了
所以它有一个问题:复杂琐碎不好理解!
仅仅知道它静态的高度还不够,我们还需要知道动态的
如何动态?监听 window.scroll 事件
如何控制图片的加载
  1. <img data-src="shanyue.jpg">
复制代码
首先设置一个临时属性 data-src,控制加载时使用 src 代替 data-src
方案二
如何判断图片出现在了当前视口
引入一个新的 API, Element.getBoundingClientRect() 方法返回元素的大小及其相对于视口的位置。
那如何判断图片出现在了当前视口呢,根据示例图示意,代码如下,这个就比较好理解了,就可以很容易地背会(就可以愉快地去面试了)。
  1. // clientHeight 代表当前视口的高度
  2. img.getBoundingClientRect().top < document.documentElement.clientHeight
复制代码
监听 window.scroll 事件也优化一下
加个节流器,提高性能。工作中一般使用 lodash.throttle 就可以了,万能的 lodash 啊!
  1. _.throttle(func, [wait=0], [options={}])
复制代码
方案三
如何判断图片出现在了当前视口
方案二使用的方法是: window.scroll 监听 Element.getBoundingClientRect() 并使用 _.throttle 节流
一系列组合动作太复杂了,于是浏览器出了一个三合一事件: IntersectionObserver API,一个能够监听元素是否到了当前视口的事件,一步到位!
事件回调的参数是 IntersectionObserverEntry 的集合,代表关于是否在可见视口的一系列值
其中,entry.isIntersecting 代表目标元素可见
  1. const observer = new IntersectionObserver((changes) => {
  2.   // changes: 目标元素集合
  3.   changes.forEach((change) => {
  4.     // intersectionRatio
  5.     if (change.isIntersecting) {
  6.       const img = change.target
  7.       img.src = img.dataset.src
  8.       observer.unobserve(img)
  9.     }
  10.   })
  11. })

  12. observer.observe(img)
复制代码
当然,IntersectionObserver 除了给图片做懒加载外,还可以对单页应用资源做预加载。
如在 next.js v9 中,会对视口内的资源做预加载
  1. <Link href="/about">
  2.   <a>关于山月</a>
  3. </Link>
复制代码
方案四
浏览器觉得懒加载这事可以交给自己做,你们开发者加个属性就好了。
  1. <img src="shanyue.jpg" loading="lazy">
复制代码
window.scroll 监听各种 top 与 height 并使用 _.throttle 节流,但是不好理解各种 top 与 hegith
window.scroll 监听 getBoundingClientRect 并使用 _.throttle 节流,没有一个统一事件,相对复杂
IntersectionObserver,浏览器推出了一个事件,方便简单
img.loading=lazy,浏览器直接给你解决,开发者直接标注属性

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

UID
434
贡献
3
丢币
0
主题
59
回帖
0
注册时间
2021-2-21
最后登录
2021-12-28