图片懒加载
图片懒加载:图片进入视口前不加载真实图,用占位(模糊小图/灰色块)占位。节省流量、加快首屏。现代浏览器有原生 loading="lazy",复杂场景用 IntersectionObserver 手动控制。
原生版:img 加 loading="lazy" 属性即可,零 JS;JS 版适合需要骨架屏过渡、动态 src 拼接、上报曝光数据的场景。
- 原生:loading="lazy" 属性,现代浏览器全部支持
- JS 版:IntersectionObserver 观察图片,进视口再赋 src
- 先放低清模糊小图占位,加载完淡入切换
HTML
<style> .lazy { display: block; width: 100%; max-width: 360px; margin: 0 auto 14px; height: 160px; border-radius: 10px; object-fit: cover; background: #f0e6ff; opacity: 0; transition: opacity .5s ease; } .lazy.on { opacity: 1; } .tip { text-align: center; color: #888; font-size: 13px; } </style> <p class="tip">下方三张图按离视口远近懒加载(打开控制台看请求)</p> <div id="lazybox" style="height:240px;overflow:auto;padding:10px"> <img class="lazy" data-src="https://picsum.photos/seed/l1/640/360"> <img class="lazy" data-src="https://picsum.photos/seed/l2/640/360"> <img class="lazy" data-src="https://picsum.photos/seed/l3/640/360"> <img class="lazy" data-src="https://picsum.photos/seed/l4/640/360"> <img class="lazy" data-src="https://picsum.photos/seed/l5/640/360"> </div> <script> var box = document.getElementById('lazybox'); if ('IntersectionObserver' in window) { var io = new IntersectionObserver(function (es) { es.forEach(function (e) { if (e.isIntersecting) { var img = e.target; img.addEventListener('load', function () { img.classList.add('on'); }); img.src = img.dataset.src; img.removeAttribute('data-src'); io.unobserve(img); } }); }, { root: box, rootMargin: '100px' }); document.querySelectorAll('.lazy').forEach(function (img) { io.observe(img); }); } else { // 兜底 document.querySelectorAll('.lazy').forEach(function (img) { img.src = img.dataset.src; img.classList.add('on'); }); } </script>
本节要点懒加载优先 loading="lazy";需要骨架/曝光统计时用 IO 版;加载完淡入。




