js面试题 图片懒加载!

一、原理

只加载可视区域内的图片,而那些还未滑动到可视区域的图片先不加载,直到用户滚动到这些资源即将可见的时候才进行加载。

若一个页面有大量的图片资源,网页首次打开时,若同时加载完这些资源,需要消耗大量的时间,利用图片懒加载,先加载部分图片,既不会影响用户体验,又能大幅提升首屏加载速度。

二、实现

1.那么如何控制图片被加载和不被加载呢?

        加载:当网页被打开时,浏览器会自动解析img标签,查看src属性,得到图片url,发请求获取图片资源。

        不加载:更改src属性名,变为data-src,这样浏览器就不会自动加载图片资源了。

注:data-* 属性是自定义数据属性,不会影响布局和表现,可以通过DOM元素身上的dataset属性获取,是HTML5引入的新功能。

2.如何判断图片是否在可视区域内呢?

        (1)视口方法

利用视口高度window.innerHeight 和 元素距离视口顶部的高getBoundingClientRect().top

若getBoundingClientRect().top < window.innerHeight,则说明元素在可视区域内

        (2)页面方法

利用元素距离页面顶部的高度offsetTop 和 页面滚动的高度document.documentElement.scrollTop 和 页面视口高度document.documentElement.clientHeight

三、代码实现

1.监听页面滚动事件

<script>
  let images = document.querySelectorAll('img');
  //监听滚动事件
  window.addEventListener('scroll',()=>{
    //滚动高度
    let scrollTop = document.documentElement.scrollTop;
    //视口高度
    let clientHeight = document.documentElement.clientHeight;

    images.forEach(image=>{
      //进入视口
      if(image.offsetTop <= scrollTop + clientHeight){
        image.src = image.dataset.src;}
    })
  })  
</script>

痛点:监听事件触发次数太多了!简单滚动就会达到上百次触发

2.优化——Intersection Observer API交叉观察器

这是一种现代的、性能更优的方法,它允许开发者定义一个回调函数,当目标元素与视口的交叉状态变化时自动触发。使用这个API可以更精确地控制懒加载行为,减少滚动事件的直接使用,从而避免潜在的性能问题。

<script>
  let images = document.querySelectorAll('img');

  //元素引入视口和离开视口都会触发一次
  const callback = (entries)=>{
    console.log('观察者');
    entries.forEach(entry=>{
      //与视口相交
      if(entry.isIntersecting){
        entry.target.src = entry.target.dataset.src;
        //图片加载过之后取消监听
        observer.unobserve(entry.target);
      }
    })
  }

  //构造observer观察器
  const observer = new IntersectionObserver(callback);
  //观察每一个图片
  images.forEach(image=>{
    observer.observe(image);
  })
</script>

  • 10
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值