目的:
节省流量,用户窗口没有看到这张图片时候不从服务器获取。
静态资源(比如图片),只有用户向下滚动,它们进入视口时才加载,这样可以节省带宽,提高网页性能。这就叫做“惰性加载”。
实现:
1. 通过web api,IntersectionObserver这个很方便。
2. 通过scroll事件监听结合获取dom调用getBoundingClientRect()判断top值就可知道是否进入视口,这种方法的缺点是,由于scroll事件密集发生,计算量很大,容易造成性能问题。
思路:
图片标签搞个默认的图片,rsrc或其他名称定义正确的图片地址,当图片标签出现在浏览器视口,src替换成rsrc的地址。
参考文档:
https://wangdoc.com/webapi/intersectionObserver.html#%E6%83%B0%E6%80%A7%E5%8A%A0%E8%BD%BD%EF%BC%88lazy-load%EF%BC%89
写法例子: // IntersectionObserver这个api学习,看文档
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>图片懒加载</title> <style> img { width: 50%; } </style> </head> <body> <div> <img src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fbig5.wallcoo.com%2Fnature%2FHokkaido_summer_field%2Fimages%2FHokkaido_summer_field_picture_13652066_3511327.jpg&refer=http%3A%2F%2Fbig5.wallcoo.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1626925159&t=62fd7414d38aa949ee7ccb330631988a" rsrc="https://gimg2.baidu.com/image_search/src=http%3A%2F%2F00.minipic.eastday.com%2F20170616%2F20170616170102_b86c160988b536fb116396593eb82f35_5.jpeg&refer=http%3A%2F%2F00.minipic.eastday.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1626925159&t=111f27373249d365ac6703ce6c176473" class="my_lazy_load"> </div> <div style="height: 80vh;background-color: green;"> </div> <div> <img src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fbig5.wallcoo.com%2Fnature%2FHokkaido_summer_field%2Fimages%2FHokkaido_summer_field_picture_13652066_3511327.jpg&refer=http%3A%2F%2Fbig5.wallcoo.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1626925159&t=62fd7414d38aa949ee7ccb330631988a" rsrc="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fattach.bbs.miui.com%2Fforum%2F201303%2F21%2F104741kyuahhougue8ekvo.jpg&refer=http%3A%2F%2Fattach.bbs.miui.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1626925159&t=09ff3b37853d2b44720fd1a9b5df0bc8" class="my_lazy_load"> </div> <div style="height: 80vh;background-color: green;"> </div> <div> <img src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fbig5.wallcoo.com%2Fnature%2FHokkaido_summer_field%2Fimages%2FHokkaido_summer_field_picture_13652066_3511327.jpg&refer=http%3A%2F%2Fbig5.wallcoo.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1626925159&t=62fd7414d38aa949ee7ccb330631988a" rsrc="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fbig5.wallcoo.com%2Fnature%2FHokkaido_summer_field%2Fimages%2FHokkaido_summer_field_picture_13652066_3511327.jpg&refer=http%3A%2F%2Fbig5.wallcoo.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1626925159&t=62fd7414d38aa949ee7ccb330631988a" class="my_lazy_load"> <img src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fbig5.wallcoo.com%2Fnature%2FHokkaido_summer_field%2Fimages%2FHokkaido_summer_field_picture_13652066_3511327.jpg&refer=http%3A%2F%2Fbig5.wallcoo.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1626925159&t=62fd7414d38aa949ee7ccb330631988a" rsrc="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fpic1.win4000.com%2Fwallpaper%2F2%2F57a2b1ac9f386.jpg&refer=http%3A%2F%2Fpic1.win4000.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1626925159&t=be6affc850e3d94e4facf13e3e4d00d4" class="my_lazy_load"> </div> <div> <img src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fbig5.wallcoo.com%2Fnature%2FHokkaido_summer_field%2Fimages%2FHokkaido_summer_field_picture_13652066_3511327.jpg&refer=http%3A%2F%2Fbig5.wallcoo.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1626925159&t=62fd7414d38aa949ee7ccb330631988a" rsrc="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fpic1.win4000.com%2Fwallpaper%2F2%2F57a2b1ac9f386.jpg&refer=http%3A%2F%2Fpic1.win4000.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1626925159&t=be6affc850e3d94e4facf13e3e4d00d4" class="my_lazy_load"> </div> <script> let observer = new IntersectionObserver((entries, observer) => { for (let i = 0; i < entries.length; i++) { let ratio = entries[i].intersectionRatio console.log(parseInt(ratio * 100) + '%', entries); if (ratio > 0.2) { let target = entries[i].target target.setAttribute("src", target.getAttribute("rsrc")) target.setAttribute("rsrc", "") // 取消观察 observer.unobserve(target) } } }, { threshold: [0.2] }) for (let item of document.getElementsByClassName("my_lazy_load")) { observer.observe(item) } </script> </body> </html>