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 相关文章推荐
JQuery的html(data)方法与&amp;lt;script&amp;gt;脚本块的解决方法
Mar 09 Javascript
父元素与子iframe相互获取变量和元素对象的具体实现
Oct 15 Javascript
禁用JavaScript控制台调试的方法
Mar 07 Javascript
JavaScript中的typeof操作符用法实例
Apr 05 Javascript
常用的Javascript设计模式小结
Dec 09 Javascript
js阻止默认浏览器行为与冒泡行为的实现代码
May 15 Javascript
Vuejs第十二篇之动态组件全面解析
Sep 09 Javascript
react性能优化达到最大化的方法 immutable.js使用的必要性
Mar 09 Javascript
angularJS模态框$modal实例代码
May 27 Javascript
妙用缓存调用链实现JS方法的重载
Apr 30 Javascript
js实现左右两侧浮动广告
Jul 09 Javascript
webpack 静态资源集中输出的方法示例
Nov 09 Javascript
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
3种平台下安装php4经验点滴
2006/10/09 PHP
PHP 杂谈《重构-改善既有代码的设计》之四 简化条件表达式
2012/04/09 PHP
PHP CURL 内存泄露问题解决方法
2015/02/12 PHP
PHP微信分享开发详解
2017/01/14 PHP
javascript 在网页中的运用(asp.net)
2009/11/23 Javascript
IE6中使用position导致页面变形的解决方案(js代码)
2011/01/09 Javascript
JS编程小常识很有用
2012/11/26 Javascript
jQuery中[attribute^=value]选择器用法实例
2014/12/31 Javascript
Jquery幻灯片特效代码分享--打开页面随机选择切换方式(3)
2015/08/15 Javascript
jquery实现清新实用的网页菜单效果
2015/08/28 Javascript
JS实现超简洁网页title标题跑动闪烁提示效果代码
2015/10/23 Javascript
分享我对JS插件开发的一些感想和心得
2016/02/04 Javascript
jquery树形菜单效果的简单实例
2016/06/06 Javascript
JavaScript利用正则表达式替换字符串中的内容
2016/12/12 Javascript
微信小程序使用字体图标的方法
2019/05/23 Javascript
node实现爬虫的几种简易方式
2019/08/22 Javascript
layui之table checkbox初始化时选中对应选项的方法
2019/09/02 Javascript
javascript设计模式 ? 迭代器模式原理与用法实例分析
2020/04/17 Javascript
微信小程序实现搜索框功能及踩过的坑
2020/06/19 Javascript
Python使用PyGreSQL操作PostgreSQL数据库教程
2014/07/30 Python
Python中捕捉详细异常信息的代码示例
2014/09/18 Python
Python实现在matplotlib中两个坐标轴之间画一条直线光标的方法
2015/05/20 Python
Python基于csv模块实现读取与写入csv数据的方法
2018/01/18 Python
python如何制作英文字典
2019/06/25 Python
Django接收自定义http header过程详解
2019/08/23 Python
基于Python实现船舶的MMSI的获取(推荐)
2019/10/21 Python
使用phonegap查找联系人的实现方法
2017/03/31 HTML / CSS
Linux管理员面试题 Linux admin interview questions
2016/07/08 面试题
品学兼优的大学生自我评价
2013/09/20 职场文书
金融专业毕业生推荐信
2013/11/26 职场文书
安全标语大全
2014/06/10 职场文书
税务干部群众路线教育实践活动自我剖析材料
2014/09/21 职场文书
考试作弊检讨书范文
2015/01/27 职场文书
2016幼儿园教师年度考核评语
2015/12/01 职场文书
护理自荐信
2019/05/14 职场文书
MySql 8.0及对应驱动包匹配的注意点说明
2021/06/23 MySQL