解析javascript图片懒加载与预加载的分析总结


Posted in Javascript onOctober 27, 2016

本篇文章主要介绍了懒加载和预加载两种技术的解析,废话不多说,一起来看吧。

懒加载也叫延迟加载:前一篇文章有介绍:JS图片延迟加载 延迟加载图片或符合某些条件时才加载某些图片。

预加载:提前加载图片,当用户需要查看时可直接从本地缓存中渲染。

两种技术的本质:两者的行为是相反的,一个是提前加载,一个是迟缓甚至不加载。懒加载对服务器前端有一定的缓解压力作用,预加载则会增加服务器前端压力。

懒加载的意义及实现方式有:

意义: 懒加载的主要目的是作为服务器前端的优化,减少请求数或延迟请求数。

实现方式:

1.第一种是纯粹的延迟加载,使用setTimeOut或setInterval进行加载延迟.

2.第二种是条件加载,符合某些条件,或触发了某些事件才开始异步下载。

3.第三种是可视区加载,即仅加载用户可以看到的区域,这个主要由监控滚动条来实现,一般会在距用户看到某图片前一定距离遍开始加载,这样能保证用户拉下时正好能看到图片。

预加载的意义及实现方式有:

预加载可以说是牺牲服务器前端性能,换取更好的用户体验,这样可以使用户的操作得到最快的反映。实现预载的方法非常多,可以用CSS(background)、JS(Image)、HTML(<img />)都可以。常用的是new Image();,设置其src来实现预载,再使用onload方法回调预载完成事件。只要浏览器把图片下载到本地,同样的src就会使用缓存,这是最基本也是最实用的预载方法。当Image下载完图片头后,会得到宽和高,因此可以在预载前得到图片的大小(方法是用记时器轮循宽高变化)。

怎么样才能实现预加载?

我们可以通过google一搜索:可以看到很多人用这种方式进行预加载:代码如下:

function loadImage(url,callback) {
  var img = new Image();
  
  img.src = url;
  img.onload = function(){
    img.onload = null;
    callback.call(img);
  }
}

为什么其他浏览器正常的:其实原因很简单,就是浏览器缓存了,除了IE6以外(即说opera也会,但是我特意用opera试了下,没有,可能版本的问题吧,或许现在已经修复了。),其他浏览器重新点击会再次执行onload方法,但是IE6是直接从浏览器取的。

那现在怎么办?最好的情况是Image可以有一个状态值表明它是否已经载入成功了。从缓存加载的时候,因为不需要等待,这个状态值就直接是表明已经下载了,而从http请求加载时,因为需要等待下载,这个值显示为未完成。这样的话,就可以搞定了。经过google搜索下即介绍:发现有一个为各个浏览器所兼容的Image的属性——complete。所以,在图片onload事件之前先对这个值做一下判断即可。最后,代码变成如下的样子:

function loadImage(url,callback) {
  var img = new Image();
  
  img.src = url;

  if(img.complete) { // 如果图片已经存在于浏览器缓存,直接调用回调函数
    
    callback.call(img);
    return; // 直接返回,不用再处理onload事件
  }

  img.onload = function(){
    img.onload = null;
    callback.call(img);
  }
}

也就是说如果图片已经在浏览器缓存里面 那么支持直接从浏览器缓存取得直接执行img.complete里面的函数 接着返回.

但是我们可以看到上面的代码:必须等图片加载完成后,可以执行回调函数,也可以说等图片加载后,我们可以获取图片的宽度和高度。那么如果我们想提前获取图片的尺寸那怎么办?上网经验告诉我:浏览器在加载图片的时候你会看到图片会先占用一块地然后才慢慢加载完毕,并且不需要预设width与height属性,因为浏览器能够获取图片的头部数据。基于此,只需要使用javascript定时侦测图片的尺寸状态便可得知图片尺寸就绪的状态。代码如下:(但是有个前提是 这个方式不是我想的,也不是我写的代码,是网上朋友总结的代码 我只是知道有这么一个原理)

var imgReady = (function(){
  var list = [],
    intervalId = null;

  // 用来执行队列
  var queue = function(){

    for(var i = 0; i < list.length; i++){
      list[i].end ? list.splice(i--,1) : list[i]();
    }
    !list.length && stop();
  };
  
  // 停止所有定时器队列
  var stop = function(){
    clearInterval(intervalId);
    intervalId = null;
  }
  return function(url, ready, error) {
    var onready = {}, 
      width, 
      height, 
      newWidth, 
      newHeight,
      img = new Image();
    img.src = url;

    // 如果图片被缓存,则直接返回缓存数据
    if(img.complete) {
      ready.call(img);
      return;
    }
    width = img.width;
    height = img.height;

    // 加载错误后的事件 
    img.onerror = function () {
      error && error.call(img);
      onready.end = true;
      img = img.onload = img.onerror = null;
    };

    // 图片尺寸就绪
    var onready = function() {
      newWidth = img.width;
      newHeight = img.height;
      if (newWidth !== width || newHeight !== height ||
        // 如果图片已经在其他地方加载可使用面积检测
        newWidth * newHeight > 1024
      ) {
        ready.call(img);
        onready.end = true;
      };
    };
    onready();
    // 完全加载完毕的事件
    img.onload = function () {
      // onload在定时器时间差范围内可能比onready快
      // 这里进行检查并保证onready优先执行
      !onready.end && onready();
      // IE gif动画会循环执行onload,置空onload即可
      img = img.onload = img.onerror = null;
    };
    
    
    // 加入队列中定期执行
    if (!onready.end) {
      list.push(onready);
      // 无论何时只允许出现一个定时器,减少浏览器性能损耗
      if (intervalId === null) {
        intervalId = setInterval(queue, 40);
      };
    };
  }
})();

调用方式如下:

imgReady('http://img01.taobaocdn.com/imgextra/i1/397746073/T2BDE8Xb0bXXXXXXXX-397746073.jpg',function(){
alert('width:' + this.width + 'height:' + this.height);
});

以上就是本文的全部内容,希望本文所述对你有所帮助,希望大家继续关注我们的网站!想要学习jsp可以继续关注本站。

Javascript 相关文章推荐
JavaScript中的对象化编程
Jan 16 Javascript
js实现的日期操作类DateTime函数代码
Mar 16 Javascript
javascript 实现 秒杀,团购 倒计时展示的记录 分享
Jul 12 Javascript
$.get获取一个文件的内容示例代码
Sep 11 Javascript
用IE重起计算机或者关机的示例代码
Mar 10 Javascript
JavaScript判断一个字符串是否包含指定子字符串的方法
Mar 18 Javascript
IE6兼容透明背景图片及解决方案
Aug 19 Javascript
jQuery 判断是否包含在数组中Array[]的方法
Aug 03 Javascript
浅谈React Native 中组件的生命周期
Sep 08 Javascript
Weex开发之地图篇的具体使用
Oct 16 Javascript
vue更改数组中的值实例代码详解
Feb 07 Javascript
纯js+css实现在线时钟
Aug 18 Javascript
js实现加载更多功能实例
Oct 27 #Javascript
Vue.js一个文件对应一个组件实践
Oct 27 #Javascript
JavaScript实现类似拉勾网的鼠标移入移出效果
Oct 27 #Javascript
node.js文件上传处理示例
Oct 27 #Javascript
Vue.js表单控件实践
Oct 27 #Javascript
vue实现可增删查改的成绩单
Oct 27 #Javascript
vuex实现简易计数器
Oct 27 #Javascript
You might like
PHP中在数据库中保存Checkbox数据(2)
2006/10/09 PHP
php函数重载的替代方法--伪重载详解
2015/05/08 PHP
Locate a File Using a File Open Dialog Box
2007/06/18 Javascript
js 限制数字 js限制输入实现代码
2012/12/04 Javascript
JS写的贪吃蛇游戏(个人练习)
2013/07/08 Javascript
JavaScript中跨域调用Flash的方法
2014/08/11 Javascript
javascript动态控制服务器控件实例
2014/09/05 Javascript
jQuery对val和atrr(&quot;value&quot;)赋值的区别介绍
2014/09/26 Javascript
angularJS中$apply()方法详解
2015/01/07 Javascript
Windows环境下npm install 报错: operation not permitted, rename的解决方法
2016/09/26 Javascript
详解js中常规日期格式处理、月历渲染和倒计时函数
2016/12/28 Javascript
js阻止移动端页面滚动的两种方法
2017/01/25 Javascript
Node.js调试技术总结分享
2017/03/12 Javascript
在vue中通过axios异步使用echarts的方法
2018/01/13 Javascript
JQuery Ajax动态加载Table数据的实例讲解
2018/08/09 jQuery
JavaScript封装的常用工具类库bee.js用法详解【经典类库】
2018/09/03 Javascript
webpack4 SplitChunks实现代码分隔详解
2019/05/23 Javascript
js中let能否完全替代IIFE
2019/06/15 Javascript
JavaScript常用内置对象用法分析
2019/07/09 Javascript
layui lay-verify form表单自定义验证规则详解
2019/09/18 Javascript
微信小程序8种数据通信的方式小结
2020/02/03 Javascript
原生JS实现记忆翻牌游戏
2020/07/31 Javascript
[01:01:23]完美世界DOTA2联赛PWL S2 Forest vs FTD.C 第一场 11.26
2020/11/30 DOTA
python实现植物大战僵尸游戏实例代码
2019/06/10 Python
python将下载到本地m3u8视频合成MP4的代码详解
2020/11/24 Python
Derek Rose官网:英国高档睡衣、家居服和内衣品牌
2020/01/18 全球购物
家长会学生家长演讲稿
2013/12/29 职场文书
精彩的英文自荐信
2014/01/30 职场文书
葬礼司仪主持词
2014/03/31 职场文书
代收款委托书范本
2014/10/01 职场文书
2015年中职班主任工作总结
2015/05/25 职场文书
工商行政处罚决定书
2015/06/24 职场文书
合作意向书怎么写
2019/06/24 职场文书
Oracle 触发器trigger使用案例
2022/02/24 Oracle
MySQL如何使备份得数据保持一致
2022/05/02 MySQL
如何用H5实现好玩的2048小游戏
2022/07/23 HTML / CSS