JS实现图片懒加载(lazyload)过程详解


Posted in Javascript onApril 02, 2020

对于图片较多的页面,使用懒加载可以大幅提高页面加载速度,提高用户体验。

懒加载的意义(为什么要使用懒加载)

对页面加载速度影响最大的就是图片,一张普通的图片可以达到几M的大小,而代码也许就只有几十KB。当页面图片很多时,页面的加载速度缓慢,几S钟内页面没有加载完成,也许会失去很多的用户。

所以,对于图片过多的页面,为了加速页面加载速度,所以很多时候我们需要将页面内未出现在可视区域内的图片先不做加载, 等到滚动到可视区域后再去加载。这样子对于页面加载性能上会有很大的提升,也提高了用户体验。

原理

将页面中的img标签src指向一张小图片或者src为空,然后定义data-src(这个属性可以自定义命名,我才用data-src)属性指向真实的图片。src指向一张默认的图片,否则当src为空时也会向服务器发送一次请求。可以指向loading的地址。

注:图片要指定宽高

<img src="default.jpg" data-src="http://ww4.sinaimg.cn/large/006y8mN6gw1fa5obmqrmvj305k05k3yh.jpg" />

当载入页面时,先把可视区域内的img标签的data-src属性值负给src,然后监听滚动事件,把用户即将看到的图片加载。这样便实现了懒加载。

代码

<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <style>
    img {
      display: block;
      margin-bottom: 50px;
      width: 400px;
      height: 400px;
    }
  </style>
</head>

<body>

  <img src="default.jpg" data-src="http://ww4.sinaimg.cn/large/006y8mN6gw1fa5obmqrmvj305k05k3yh.jpg" alt="">
  <img src="default.jpg" data-src="http://ww4.sinaimg.cn/large/006y8mN6gw1fa5obmqrmvj305k05k3yh.jpg" alt="">
  <img src="default.jpg" data-src="http://ww1.sinaimg.cn/large/006y8mN6gw1fa7kaed2hpj30sg0l9q54.jpg" alt="">
  <img src="default.jpg" data-src="http://ww1.sinaimg.cn/large/006y8mN6gw1fa7kaed2hpj30sg0l9q54.jpg" alt="">
  <img src="default.jpg" data-src="http://ww4.sinaimg.cn/large/006y8mN6gw1fa5obmqrmvj305k05k3yh.jpg" alt="">
  <img src="default.jpg" data-src="http://ww4.sinaimg.cn/large/006y8mN6gw1fa5obmqrmvj305k05k3yh.jpg" alt="">
  <img src="default.jpg" data-src="http://ww4.sinaimg.cn/large/006y8mN6gw1fa5obmqrmvj305k05k3yh.jpg" alt="">
  <img src="default.jpg" data-src="http://ww4.sinaimg.cn/large/006y8mN6gw1fa5obmqrmvj305k05k3yh.jpg" alt="">
  <img src="default.jpg" data-src="http://ww1.sinaimg.cn/large/006y8mN6gw1fa7kaed2hpj30sg0l9q54.jpg" alt="">
  <img src="default.jpg" data-src="http://ww4.sinaimg.cn/large/006y8mN6gw1fa5obmqrmvj305k05k3yh.jpg" alt="">
  <img src="default.jpg" data-src="http://ww4.sinaimg.cn/large/006y8mN6gw1fa5obmqrmvj305k05k3yh.jpg" alt="">

</body>

JavaScript

<script>
  var num = document.getElementsByTagName('img').length;
  var img = document.getElementsByTagName("img");
  var n = 0; //存储图片加载到的位置,避免每次都从第一张图片开始遍历

  lazyload(); //页面载入完毕加载可是区域内的图片

  window.onscroll = lazyload;

  function lazyload() { //监听页面滚动事件
    var seeHeight = document.documentElement.clientHeight; //可见区域高度
    var scrollTop = document.documentElement.scrollTop || document.body.scrollTop; //滚动条距离顶部高度
    for (var i = n; i < num; i++) {
      if (img[i].offsetTop < seeHeight + scrollTop) {
        if (img[i].getAttribute("src") == "default.jpg") {
          img[i].src = img[i].getAttribute("data-src");
        }
        n = i + 1;
      }
    }
  }
</script>

jQuery

<script>
  var n = 0,
    imgNum = $("img").length,
    img = $('img');

  lazyload();

  $(window).scroll(lazyload);

  function lazyload(event) {
    for (var i = n; i < imgNum; i++) {
      if (img.eq(i).offset().top < parseInt($(window).height()) + parseInt($(window).scrollTop())) {
        if (img.eq(i).attr("src") == "default.jpg") {
          var src = img.eq(i).attr("data-src");
          img.eq(i).attr("src", src);

          n = i + 1;
        }
      }
    }
  }
</script>

使用节流函数进行性能优化

如果直接将函数绑定在scroll事件上,当页面滚动时,函数会被高频触发,这非常影响浏览器的性能。

我想实现限制触发频率,来优化性能。

节流函数:只允许一个函数在N秒内执行一次。下面是一个简单的节流函数:

// 简单的节流函数
//fun 要执行的函数
//delay 延迟
//time 在time时间内必须执行一次
function throttle (fun, delay, time) {
 let timeout

 let startTime = new Date()

 return function () {
  let context = this

  let args = Array.prototype.slice.call(arguments)

  let curTime = new Date()

  clearTimeout(timeout)
  if (curTime - startTime >= time) {
   // 如果达到了规定的触发时间间隔,触发 handler
   fun.apply(context, args)
   startTime = curTime
  } else {
   // 没达到触发间隔,重新设定定时器
   timeout = setTimeout(function () {
    fun.apply(context, args)
   }, delay)
  }
 }
};
// 实际想绑定在 scroll 事件上的 handler
function lazyload(event) {}
// 采用了节流函数
window.addEventListener('scroll',throttle(lazyload,500,1000));

使用去抖函数进行性能优化

去抖相比较节流函数要稍微简单一点,去抖是让函数延迟执行,而节流比去抖多了一个在一定时间内必须要执行一次。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JavaScript 继承机制的实现(待续)
May 18 Javascript
SyntaxHighlighter语法高亮插件使用说明
Aug 14 Javascript
基于jquery扩展漂亮的下拉框可以二次修改
Nov 19 Javascript
node.js中的console.time方法使用说明
Dec 09 Javascript
jQuery实现点击某个div打开层,点击其他div关闭层实例分析(阻止冒泡)
Nov 18 Javascript
JS基于for语句编写的九九乘法表示例
Jan 04 Javascript
JS实现基于拖拽改变物体大小的方法
Jan 23 Javascript
vue组件中iview的modal组件爬坑问题之modal的显示与否应该是使用v-show
Apr 12 Javascript
关于vue里页面的缓存详解
Nov 04 Javascript
微信小程序聊天功能的示例代码
Jan 13 Javascript
详解Vue 数据更新了但页面没有更新的 7 种情况汇总及延伸总结
May 28 Javascript
vue elementUI批量上传文件
Apr 26 Vue.js
JavaScript运动原理基础知识详解
Apr 02 #Javascript
基于js实现逐步显示文字输出代码实例
Apr 02 #Javascript
webpack3.0升级4.0的方法步骤
Apr 02 #Javascript
Javascript模块化机制实现原理详解
Apr 02 #Javascript
sharp.js安装过程中遇到的问题总结
Apr 02 #Javascript
viewer.js一个强大的基于jQuery的图像查看插件(支持旋转、缩放)
Apr 01 #jQuery
Selenium执行Javascript脚本参数及返回值过程详解
Apr 01 #Javascript
You might like
学习discuz php 引入文件的方法DISCUZ_ROOT
2009/06/21 PHP
PHP简单实现无限级分类的方法
2016/05/13 PHP
遍历指定目录,并存储目录内所有文件属性信息的php代码
2016/10/28 PHP
PHP会话控制实例分析
2016/12/24 PHP
jquery ajax jsonp跨域调用实例代码
2013/12/11 Javascript
一个简单的动态加载js和css的jquery代码
2014/09/01 Javascript
JavaScript实现点击按钮直接打印
2016/01/06 Javascript
Bootstrap基本样式学习笔记之表格(2)
2016/12/07 Javascript
深入理解JavaScript中的尾调用(Tail Call)
2017/02/07 Javascript
Node.js连接MongoDB数据库产生的问题
2017/02/08 Javascript
JavaScript观察者模式(publish/subscribe)原理与实现方法
2017/03/30 Javascript
微信小程序 同步请求授权的详解
2017/08/04 Javascript
select自定义小三角样式代码(实用总结)
2017/08/18 Javascript
Node.js利用断言模块assert进行单元测试的方法
2017/09/28 Javascript
vue 组件高级用法实例详解
2018/04/11 Javascript
JS代码屏蔽F12,右键,粘贴,复制,剪切,选中,操作实例
2019/09/17 Javascript
[59:42]Secret vs Alliacne 2019国际邀请赛小组赛 BO2 第一场 8.15
2019/08/17 DOTA
python 性能提升的几种方法
2016/07/15 Python
Python(Django)项目与Apache的管理交互的方法
2018/05/16 Python
Django实现简单网页弹出警告代码
2019/11/15 Python
让你的Python代码实现类型提示功能
2019/11/19 Python
Python run()函数和start()函数的比较和差别介绍
2020/05/03 Python
Java ExcutorService优雅关闭方式解析
2020/05/30 Python
Python代码需要缩进吗
2020/07/01 Python
使用bandit对目标python代码进行安全函数扫描的案例分析
2021/01/27 Python
scrapy-splash简单使用详解
2021/02/21 Python
css3弹性盒模型实例介绍
2013/05/27 HTML / CSS
详解Html5微信支付爬坑之路
2018/07/24 HTML / CSS
学习心得体会
2014/01/01 职场文书
汽车专业学生自我评价
2014/01/19 职场文书
优秀学生评语大全
2014/04/25 职场文书
银行纠风工作实施方案
2014/06/08 职场文书
教师工作总结范文2014
2014/11/10 职场文书
劳模事迹材料范文
2014/12/24 职场文书
车间安全生产管理制度
2015/08/06 职场文书
Vue3如何理解ref toRef和toRefs的区别
2022/02/18 Vue.js