前言:图片懒加载是一种对网页性能优化的方式,当访问一个页面的时候,优先加载可视区域的图片,而不是一次性把页面中的图片都请求加载出来。通过这种方式可以使页面加载速度变快,减轻服务器的压力,节省流量。
- 简单来说:就是不一次性加载那么多图片,而是慢慢来,按需加载。
- 比较建议的方法是通过 IntesectionObserve 这个API来实现
实现原理
- 首先获取当前元素距离顶部的距离
- 再获取屏幕的高度
主要方法:
1 2
| 1,DOMobj.getBoundingClientRect().top 2,window.innerHeight
|
简易版懒加载
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| <body> <div class="box"> <img data-src="image1.jpg" class="lazy-load" src="loading.gif" alt="1" srcset=""> <img data-src="image2.jpg" class="lazy-load" src="loading.gif" alt="2" srcset=""> <img data-src="image3.jpg" class="lazy-load" src="loading.gif" alt="3" srcset=""> <img data-src="image4.jpg" class="lazy-load" src="loading.gif" alt="4" srcset=""> <img data-src="image5.jpg" class="lazy-load" src="loading.gif" alt="5" srcset=""> <img data-src="image6.jpg" class="lazy-load" src="loading.gif" alt="6" srcset=""> <img data-src="image7.jpg" class="lazy-load" src="loading.gif" alt="7" srcset=""> </div> </body>
<style> .box{ width: 50%; margin: 0 auto; }
.box img{ width: 100%; height: 100%; }
</style>
<script> function imgLazyLoad(){ var imgs = [...document.querySelectorAll('.lazy-load')] imgs.forEach(img => { if(img.getBoundingClientRect().top < window.innerHeight){ img.src = img.dataset.src } }); }
window.onload = imgLazyLoad; window.addEventListener('scroll',imgLazyLoad)
</script>
|
效果
优化
监听鼠标滚轮过于频繁,应该进行节流优化一下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| <script> function imgLazyLoad(){ var imgs = [...document.querySelectorAll('.lazy-load')] imgs.forEach(img => { if(img.getBoundingClientRect().top < window.innerHeight){ img.src = img.dataset.src } }); }
window.onload = imgLazyLoad; var listenScroll = true window.addEventListener('scroll',() =>{ if(!listenScroll){ return ; }else{ setTimeout(() =>{ imgLazyLoad() listenScroll = true },300); listenScroll = false } }) </script>
|
再优化(最好的方法)
- 上面这种方式虽然也实现了懒加载,但是还是有一点缺点,就是一当发生滚动事件时,就发生了大量的循环和判断操作判断图片是否可视区里。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| const images = document.querySelectorAll('.lazy-load');
function lazyLoad(entries, observer) { entries.forEach(entry => { if (entry.isIntersecting) { const img = entry.target; img.src = img.dataset.src; observer.unobserve(img); } }); }
const options = { root: null, rootMargin: '0px', threshold: 0.1 };
const observer = new IntersectionObserver(lazyLoad, options);
images.forEach(img => { observer.observe(img); });
|