图片懒加载方案

一、img标签loading属性

loading:指示浏览器应当如何加载该图像。允许的值:

eager:立即加载图像,不管它是否在可视视口(visible viewport)之外(默认值)。

lazy:延迟加载图像,直到它和视口接近到一个计算得到的距离(由浏览器定义)。目的是在需要图像之前,避免加载图像所需要的网络和存储带宽。这通常会提高大多数典型用场景中内容的性能。

视口距离阈值:不同浏览器有不同的"接近视口"标准,通常为:

  • Chrome:距离视口约1250px时开始加载
  • Firefox:距离视口约1000px时开始加载

如何判断当前浏览器是否支持loading=”lazy”

var isSupportLoading = 'loading' in document.createElement('img');
var isSupportLoading = 'loading' in new Image();
var isSupportLoading = 'loading' in HTMLImageElement.prototype;

如何获取loading属性值

var attrLoading = img.loading;

二、监听scroll事件,元素是否在视口内

监听scroll事件,获取img元素相对于视口的顶点位置 el.getBoundingClientRect().top,只要这个值小于浏览器的高度 window.innerHeight 就说明进入可视区域,当图片进入可视区域时再去加载图片资源。

图片刚开始显示的是默认图片,当进入可视区域时,用 data-src 的真实图片地址赋值给 src。

<img src="default.jpg" data-src="http://www.xxx.jpg" />

 

三、IntersectionObserver

const observer = new IntersectionObserver(callback, options);

options 配置项:

  • root:观察的根元素(默认是视口 null)。
  • rootMargin:扩展/缩小根元素的检测范围(如 "10px 20px"。
  • threshold:触发回调的交叉比例阈值(如 [0, 0.5, 1] 表示 0%、50%、100% 可见时触发)。

callback 回调函数: 接收 entries 数组,每个 entry 包含:

  • isIntersecting:目标是否进入视口。
  • intersectionRatio:当前交叉比例。

代码示例:

<img data-src="image.jpg" class="lazy-img"><script>
  const observer = new IntersectionObserver((entries) => {
    entries.forEach(entry => {
      if (entry.isIntersecting) {
        const img = entry.target;
        img.src = img.dataset.src; // 替换真实URL
        observer.unobserve(img); // 停止观察已加载图片
      }
    });
  }, { threshold: 0.1 }); // 10%可见时触发
​
  document.querySelectorAll('.lazy-img').forEach(img => observer.observe(img));
</script>

结合vue封装自定义指令

/* 图片懒加载指令 */
  Vue.directive('lazyload', {
    inserted: (el, binding) => {
      const options = {
        rootMargin: '0px 0px 300px 0px',
        threshold: 0.1
      };
      const observer = new IntersectionObserver((entries, observer) => {
        entries.forEach(entry => {
          if (entry.isIntersecting) {
            const img = entry.target;
            img.src = binding.value;
            observer.unobserve(img);
          }
        });
      }, options);

      observer.observe(el);
    }
  });

 

posted @ 2025-07-15 17:45  盼星星盼太阳  阅读(19)  评论(0)    收藏  举报