图片懒加载方案
一、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); } });

浙公网安备 33010602011771号