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 相关文章推荐
CSS常用网站布局实例
Apr 03 Javascript
用jquery设置按钮的disabled属性的实现代码
Nov 28 Javascript
JavaScript回调(callback)函数概念自我理解及示例
Jul 04 Javascript
jQuery实现冻结表头的方法
Mar 09 Javascript
jquery分割字符串的方法
Jun 24 Javascript
实例代码详解javascript实现窗口抖动及qq窗口抖动
Jan 04 Javascript
jQuery 添加样式属性的优先级别方法(推荐)
Jun 08 jQuery
js使用highlight.js高亮你的代码
Aug 18 Javascript
AngularJS中filter的使用实例详解
Aug 25 Javascript
JavaScript实现HSL拾色器
May 21 Javascript
JavaScript Window浏览器对象模型原理解析
May 30 Javascript
Nuxt的动态路由和参数校验操作
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
PHP文章采集URL补全函数(FormatUrl)
2012/08/02 PHP
php strftime函数的详细用法
2018/06/21 PHP
laravel5使用freetds连接sql server的方法
2018/12/07 PHP
php常用日期时间函数实例小结
2019/07/04 PHP
input+select(multiple) 实现下拉框输入值
2009/05/21 Javascript
基于jquery的文本框与autocomplete结合使用(asp.net+json)
2012/05/30 Javascript
javascript full screen 全屏显示页面元素的方法
2013/09/27 Javascript
JSONP跨域的原理解析及其实现介绍
2014/03/22 Javascript
JavaScript字符串对象substr方法入门实例(用于截取字符串)
2014/10/16 Javascript
Jquery 分页插件之Jquery Pagination
2015/08/25 Javascript
JS面向对象(3)之Object类,静态属性,闭包,私有属性, call和apply的使用,继承的三种实现方法
2016/02/25 Javascript
JavaScript实现类似淘宝的购物车效果
2017/03/16 Javascript
nodejs 使用 js 模块的方法实例详解
2018/12/04 NodeJs
VUE引入第三方js包及调用方法讲解
2019/03/01 Javascript
JavaScript跳出循环的三种方法(break, return, continue)
2019/07/30 Javascript
解决vue-cli@3.xx安装不成功的问题及搭建ts-vue项目
2020/02/09 Javascript
JS轮播图的实现方法
2020/08/24 Javascript
[01:48]2018DOTA2亚洲邀请赛主赛事第二日五佳镜头 VG完美团战逆转TNC
2018/04/05 DOTA
Python实现windows下模拟按键和鼠标点击的方法
2015/03/13 Python
python实现用户登录系统
2016/05/21 Python
Python3.6实现连接mysql或mariadb的方法分析
2018/05/18 Python
快速解决PyCharm无法引用matplotlib的问题
2018/05/24 Python
Pycharm导入Python包,模块的图文教程
2018/06/13 Python
python文件绝对路径写法介绍(windows)
2019/12/25 Python
CSS3径向渐变之大鱼吃小鱼之孤单的大鱼
2016/04/26 HTML / CSS
探讨HTML5移动开发的几大特性(必看)
2015/12/30 HTML / CSS
正宗的日本零食和糖果订阅盒:Bokksu
2019/11/21 全球购物
建筑专业自荐信
2013/10/18 职场文书
中医专业职业生涯规划书范文
2014/01/04 职场文书
如何撰写一封出色的求职信
2014/04/27 职场文书
考博专家推荐信
2014/05/10 职场文书
机电系毕业生求职信
2014/07/11 职场文书
2014年公务员个人工作总结
2014/11/22 职场文书
古诗文之爱国名句(77句)
2019/09/24 职场文书
分析Python list操作为什么会错误
2021/11/17 Python
《传颂之物 虚伪的假面》BD发售宣传CM公开
2022/04/04 日漫