图片懒加载,顾名思义,就是滑动页面到能看到图片的时候再加载图片。
对于图片懒加载而言,可以分为两部分进行考虑:①判断图片进入到可视窗口 ②控制图片进行加载
0. 为什么懒加载?
对于首屏之外的内容,特别是图片和视频,一方面由于资源文件很大,若是全部加载完成,既费时又费力,还容易阻塞渲染引起卡顿;另一方面,就算加载完成用户也不一定浏览到全部内容,如果首屏没有吸引到用户,很可能整个页面都会被关闭。
所以,在首次打开网站时,应尽量只加载首屏内容,首屏之外的图片或视频可以等到用户滑动到的时候再加载。
1. 实现方式:
方式一:位置计算 + 监听滚动事件 + DataSet API
👉 判断图片出现在窗口中需要用到clientTop
,offsetTop
,clientHeight
以及 scrollTop
各种关于图片的高度作比对
(一堆东西也记不住,不如,放过自己?)
👉 监听 window.scroll
事件
👉 控制图片加载
<img data-src="shanyue.jpg">
首先设置一个临时 Data
属性 data-src
,控制加载时使用 src
代替 data-src
,可利用 DataSet API
实现
img.src = img.datset.src
方式二:getBoundingClientRect API + Scroll with Throttle + DataSet API
👉 getBoundingClientRecy()
函数获取元素的相对位置。
getBoundingClientRecy().top 、 getBoundingClientRecy().bottom 、 getBoundingClientRecy().left 、 getBoundingClientRecy().right
位置如下所示:
如何判断图片出现在了当前视口?
img.getBoundingClientRect().top < document.documentElement.clientHeight
👉 优化window.scroll
事件
加个节流器,提高性能。工作中一般使用 lodash.throttle 就可以了。
_.throttle(func, [wait=0], [options={}])
👉 控制图片加载 同方式一
方式三:IntersectionObserver API + DataSet API
⚡ 方案二使用的方法是: window.scroll
监听 Element.getBoundingClientRect()
并使用 _.throttle
节流
👉 一系列组合动作太复杂了,于是浏览器出了一个三合一事件: Intersection Observer API
,一个能够监听元素是否到了当前视口的事件,一步到位!
关于Intersection Observer API
的简述:
每当因页面滚动或者窗口尺寸发生变化,使得目标元素(target)与设备视窗或其他指定元素产生交集时,便会触发Intersection Observer API
配置的回调函数,在该回调函数中进行延迟加载的逻辑处理。
1 | const observer = new IntersectionObserver((changes) => { |
方式四:LazyLoading属性
浏览器觉得懒加载这事可以交给自己做,你们开发者加个属性就好了。缺点就是兼容性存在问题。 <img src="shanyue.jpg" loading="lazy">