JavaScript实现图片懒加载的三种方案详解

 更新时间:2023年12月26日 08:20:12   作者:起风了啰  
图片懒加载,当图片出现在可视区域再进行加载,提升用户的体验,这篇文章主要为大家整理了三个常用的图片懒加载实现方法,希望对大家有所帮助

一、前言

图片懒加载,当图片出现在可视区域再进行加载,提升用户的体验。因为有些用户不会看完图片,全部加载会浪费流量。在网上查阅资料,总结了三种办法,有各自的利弊,下文一一介绍。

方法优点缺点推荐指数
设置img loadingh5的属性,没有兼容问题需要已知图片高度、宽高比⭐️⭐️
IntersectionObserver API无需知道图片高度低版本需引入polyfill⭐️⭐️⭐️
vue-lazyload 自定义指令无需知道图片高度github现存issues较多,没有解决⭐️⭐️

二、实现方式及Demo

1. 设置img标签loading属性

loading属性允许两个值:eager立即加载图像(默认值);lazy延迟加载图像。在使用lazy属性的时候,需要设置<img>标签的高度,否则无法懒加载。

注意: 适用于两种场景,图片高度已知、图片宽高比已知。

已知图片高度

<style>
  .img-box img {
    width: 100%;
    height: 700px; /*设置为图片的真实高度*/
  }
</style>

<div class="img-box">
  <img src="https://i.postimg.cc/GtN3Cs02/1.jpg" loading="lazy" />
  <img src="https://i.postimg.cc/hGdKLGdW/2.jpg" loading="lazy" />
  <img src="https://i.postimg.cc/T1SkJTbF/3.jpg" loading="lazy" />
  <img src="https://i.postimg.cc/wxPFPTtb/4.jpg" loading="lazy" />
  <img src="https://i.postimg.cc/FRkGF28x/5.jpg" loading="lazy" />
  <img src="https://i.postimg.cc/05JH9wqq/6.jpg" loading="lazy" />
</div>

已知图片宽高比

 <style>
  .img-box div {
    position: relative;
    padding-top: 66%; /* (你的图片的高度/宽度值) */
    overflow: hidden;
  }
  .img-box img {
    position: absolute;
    top:0;
    right:0;
    width:100%;
  }
</style>

<div class="img-box">
  <div>
    <img src="https://i.postimg.cc/GtN3Cs02/1.jpg" loading="lazy" />
  </div>
  <div>
    <img src="https://i.postimg.cc/hGdKLGdW/2.jpg" loading="lazy" />
  </div>
  <div>
    <img src="https://i.postimg.cc/T1SkJTbF/3.jpg" loading="lazy" />
  </div>
  <div>
    <img src="https://i.postimg.cc/wxPFPTtb/4.jpg" loading="lazy" />
  </div>
  <div>
    <img src="https://i.postimg.cc/FRkGF28x/5.jpg" loading="lazy" />
  </div>
  <div>
    <img src="https://i.postimg.cc/05JH9wqq/6.jpg" loading="lazy" />
  </div>
</div>

2. 使用 IntersectionObserver

IntersectionObserver接口,可以观察DOM节点是否出现在视口,当DOM节点出现在视口中才加载图片。img必须有高度,否则图片默认都在视口中,会将图片全部加载。可以设置img的src为base64白色图片,然后在替换为真实的图片地址。

注意: 不需要预先知道图片的高度,但是有兼容性问题,低版本需要引入intersection-observer polyfill

已知图片高度

<style>
    .img-box .lazy-img {
        width: 100%;
        height: 600px; /*如果已知图片高度可以设置*/
    }
</style>

<div class="img-box">
  <img class="lazy-img" data-origin="https://images.djtest.cn/pic/test/d48aed7c991b43d850d011f2299d852e.jpg" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"/>
  <img class="lazy-img" data-origin="https://images.djtest.cn/pic/test/a588b152c79ac60162ecbdf82b060061.jpg" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"/>
  <img class="lazy-img" data-origin="https://images.djtest.cn/pic/test/eacbc2cd4b6ca636077378182bdfcc88.jpg" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"/>
  <img class="lazy-img" data-origin="https://images.djtest.cn/pic/test/751470f4b478450e8556f78cd7dd3d96.jpg" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"/>
  <img class="lazy-img" data-origin="https://images.djtest.cn/pic/test/e4a531bee5694a4a01dee74b18bbfd8b.jpg" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"/>
  <img class="lazy-img" data-origin="https://images.djtest.cn/pic/test/7d8f107e827a7beaa0b9d231bfa4187f.jpg" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"/>
  <img class="lazy-img" data-origin="https://images.djtest.cn/pic/test/4f7586f6b74f2bd0b94004fcbae69856.jpg" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"/>
  <img class="lazy-img" data-origin="https://images.djtest.cn/pic/test/863849e14e7e8903ed4b27fcbdafe8b0.jpg" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"/>
  <img class="lazy-img" data-origin="https://images.djtest.cn/pic/test/d8bb17fe9a7223f35075014ef250e2fa.jpg" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"/>
</div>

<script>
    function Observer() {
        let images = document.querySelectorAll(".lazy-img");
        let observer = new IntersectionObserver(entries => {
            entries.forEach(item => {
                if (item.isIntersecting) {
                    item.target.src = item.target.dataset.origin; // 开始加载图片,把data-origin的值放到src
                    observer.unobserve(item.target); // 停止监听已开始加载的图片
                }
            });
        });
        images.forEach(img => observer.observe(img));
    }
    Observer()
</script>

3. 使用vue-lazyload

在vue2中使用时,建议安装npm i vue-lazyload@1.3.3 -s,使用高版本在main.js中全局自定义指令后依然无法使用指令。在vue3中可以使用 npm i vue3-lazy -s

全局注册自定义指令,在页面就可以使用了

// 全局自定义指令
import Vue from 'vue'
import VueLazyload from 'vue-lazyload'
Vue.use(VueLazyload, {
  preLoad: 1,
  observer: true // 设置为true,内部使用IntersectionObserver。默认使用
})
/* 在页面中直接使用 */
<div>
    <img v-lazy="https://images.djtest.cn/pic/test/d48aed7c991b43d850d011f2299d852e.jpg">
    <img v-lazy="https://images.djtest.cn/pic/test/a588b152c79ac60162ecbdf82b060061.jpg">
    <img v-lazy="https://images.djtest.cn/pic/test/eacbc2cd4b6ca636077378182bdfcc88.jpg">
    <img v-lazy="https://images.djtest.cn/pic/test/751470f4b478450e8556f78cd7dd3d96.jpg">
</div>

以上就是JavaScript实现图片懒加载的三种方案详解的详细内容,更多关于JavaScript图片懒加载的资料请关注脚本之家其它相关文章!

相关文章

  • JavaScript空值处理的最佳实践指南

    JavaScript空值处理的最佳实践指南

    早期我们常用 ||(逻辑或)实现,但它常会把 0、空字符串 、false 这类合法假值误判为空值,导致业务逻辑出错,本文从 || 到??,给大家介绍了JavaScript空值处理的最佳实践指南,需要的朋友可以参考下
    2026-03-03
  • javascript设计模式 – 原型模式原理与应用实例分析

    javascript设计模式 – 原型模式原理与应用实例分析

    这篇文章主要介绍了javascript设计模式 – 原型模式,结合实例形式分析了javascript原型模式相关概念、原理、应用场景及操作注意事项,需要的朋友可以参考下
    2020-04-04
  • QQ强制聊天功能代码(加强版,兼容QQ2010)

    QQ强制聊天功能代码(加强版,兼容QQ2010)

    QQ强制聊天功能代码,脚本之家以前也发布过,但已经不能用了,这个是新版本,经过测试,完全兼容新版本的qq.
    2010-06-06
  • 微信小程序版翻牌小游戏

    微信小程序版翻牌小游戏

    这篇文章主要为大家详细介绍了微信小程序版翻牌小游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-01-01
  • js实现本地时间同步功能

    js实现本地时间同步功能

    这篇文章主要为大家详细介绍了js实现本地时间同步功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-08-08
  • Webpack打包字体font-awesome的方法示例

    Webpack打包字体font-awesome的方法示例

    本篇文章主要介绍了Webpack打包字体font-awesome的方法示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-04-04
  • javaScript事件学习小结(四)event的公共成员(属性和方法)

    javaScript事件学习小结(四)event的公共成员(属性和方法)

    这篇文章主要介绍了javaScript事件学习小结(四)event的公共成员(属性和方法)的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2016-06-06
  • webpack多页面开发实践

    webpack多页面开发实践

    这篇文章主要介绍了webpack多页面开发实践,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-12-12
  • JavaScript 手动实现instanceof的方法

    JavaScript 手动实现instanceof的方法

    instanceof运算符用于检测构造函数的prototype属性是否出现在某个实例对象的原型链上,本文重点给大家介绍JavaScript手动实现instanceof的问题,感兴趣的朋友跟随小编一起看看吧
    2021-10-10
  • Openlayers显示瓦片网格信息的方法

    Openlayers显示瓦片网格信息的方法

    这篇文章主要为大家详细介绍了Openlayers显示瓦片网格信息,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-09-09

最新评论