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 相关文章推荐
js判断数据类型如判断是否为数组是否为字符串等等
Jan 15 Javascript
js实现使用鼠标拖拽切换图片的方法
May 04 Javascript
JavaScript模版引擎的基本实现方法浅析
Feb 15 Javascript
一个超简单的jQuery回调函数例子(分享)
Aug 08 Javascript
微信小程序去哪里找 小程序到底如何使用(附小程序名单)
Jan 09 Javascript
react.js 翻页插件实例代码
Jan 19 Javascript
在node.js中怎么屏蔽掉favicon.ico的请求
Mar 01 Javascript
ionic 3.0+ 项目搭建运行环境的教程
Aug 09 Javascript
react-native 完整实现登录功能的示例代码
Sep 11 Javascript
vue环境搭建简单教程
Nov 07 Javascript
详解vue项目的构建,打包,发布全过程
Nov 23 Javascript
jQuery实现带3D切割效果的轮播图功能示例【附源码下载】
Apr 04 jQuery
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
PHP 采集程序中常用的函数
2009/12/09 PHP
php学习之数据类型之间的转换介绍
2011/06/09 PHP
探讨各种PHP字符串函数的总结分析
2013/06/05 PHP
查找php配置文件php.ini所在路径的二种方法
2014/05/26 PHP
PHP使用array_merge重新排列数组下标的方法
2015/07/22 PHP
PHP中文字符串截断无乱码解决方法
2016/10/10 PHP
ModelDialog JavaScript模态对话框类代码
2011/04/17 Javascript
禁用键盘上的(全局)指定键兼容iE、Chrome、火狐
2013/05/14 Javascript
jQuery实现类似淘宝购物车全选状态示例
2013/06/26 Javascript
javascript实现博客园页面右下角返回顶部按钮
2015/02/22 Javascript
javascript实现图像循环明暗变化的方法
2015/02/25 Javascript
javascript递归回溯法解八皇后问题
2015/04/22 Javascript
jquery插件之文字间歇自动向上滚动效果代码
2016/02/25 Javascript
微信 java 实现js-sdk 图片上传下载完整流程
2016/10/21 Javascript
利用js+css+html实现固定table的列头不动
2016/12/08 Javascript
详解nodeJS中读写文件方法的区别
2017/03/06 NodeJs
使用重写url机制实现验证码换一张功能
2017/08/01 Javascript
十个免费的web前端开发工具详细整理
2017/09/18 Javascript
JS前端基于canvas给图片添加水印
2020/11/11 Javascript
[01:01:52]DOTA2-DPC中国联赛定级赛 SAG vs iG BO3第二场 1月9日
2021/03/11 DOTA
python基础教程之获取本机ip数据包示例
2014/02/10 Python
python服务器与android客户端socket通信实例
2014/11/12 Python
用Python写冒泡排序代码
2016/04/12 Python
深入浅析Python 中 is 语法带来的误解
2019/05/07 Python
Django中信号signals的简单使用方法
2019/07/04 Python
python版百度语音识别功能
2019/07/09 Python
快速解决Django关闭Debug模式无法加载media图片与static静态文件
2020/04/07 Python
python爬虫用mongodb的理由
2020/07/28 Python
用 python 进行微信好友信息分析
2020/11/28 Python
HTML5 Canvas渐进填充与透明实现图像的Mask效果
2013/07/11 HTML / CSS
工地例会施工汇报材料
2014/08/22 职场文书
小学生感恩老师演讲稿
2014/08/28 职场文书
社区班子个人对照检查材料思想汇报
2014/10/07 职场文书
教师党员自我评议不足范文
2014/10/19 职场文书
祝福语集锦:送给闺蜜的生日祝福语
2019/10/08 职场文书
js实现模拟购物商城案例
2021/05/18 Javascript