图片懒加载,即当图片进入显示器“视口”时,再来加载相应的图片。这样做的目的有两个:
1.当一个网页图片数量特别多时,浏览器可以先加载在视口中的。而不在视口中的可以等滚动到视口中时再来加载,这样就不会造成后面的图片加载时占用网络而影响前面的图片传输,从而影响客户体验的问题。
2.可以节约用户的流量。
而我们比较熟悉的关于浏览器元素位置的API就是getBoundingClientRect(),可以获取到元素相对于视口的位置,从而实现元素的加载。但是这个API是需要监听scroll事件的,如果scroll事件密集触发,计算量很大,容易造成性能问题。所以我们今天想要介绍IntersectionObserver这个浏览器API来实现图片懒加载的功能。
文中会结合一个react的demo项目,来讲解在真实场景中,我们具体应该如何应用IntersectionObserver,下面用项目搭建的过程来讲解。
1.项目搭建:
可以先用create-react-app这个脚手架来搭建一个demo:(命令参考 create-react-app.dev/docs/gettin… )
2.在搭建完项目后,可以对react的demo中App.js文件作如下改动:
引入LazyLoadImage组件,并且用图片链接的地址来渲染LazyLoadImage组件。下面我们来看LazyLoadImage组件是如何实现的:
在LazyLoadImage组件中,使用useRef先获取到了图片的DOM实例,然后在组件加载的时候通过window中注入的ImgIntersectionInstance对象的observe方法来进行观察。 组件最后返回的是一个img标签,在标签中通过data-src属性传入了图片的地址,为了方便观察,后面设定了图片的样式。
3.下面来介绍window中的ImgIntersectionInstance方法是怎样被注入的,在项目的入口文件中引入了下面的LazyLoadLogic文件:
文件中new了一个IntersectionObserver对象,第一个参数为传入的一个函数,用来处理触发这个API时执行的事件,其中entries为处罚这个事件的DOM对象。在箭头函数中可以看出如果每一项的isIntersecting为true,就执行loadItem函数,底部的loadItem函数将DOM元素中data-src的属性值赋给了src,并且取消监听,这样就实现了图片的加载。
而实例化IntersectionObserver对象的第二个参数rootMargin表示,如果默认把浏览器的视口和所要检测的元素的交集作为触发第一个函数参数的条件,为视口所添加margin值。这里为了实现一个图片预加载的功能,就是差350px进入视口时就开始图片加载。此处想要获得更详细的解释可以参考结尾阮一峰的博客和官方说明。
下面就来看一下懒加载的效果,后面的图片必须往后下滚动,才能够打印出...loaded的日志。
参考:
阮一峰博客:www.ruanyifeng.com/blog/2016/1…
MDN:developer.mozilla.org/zh-CN/docs/…