解析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 相关文章推荐
return false;和e.preventDefault();的区别
Jul 11 Javascript
js 关键词高亮(根据ID/tag高亮关键字)案例介绍
Jan 21 Javascript
浅析offsetLeft,Left,clientLeft之间的区别
Nov 30 Javascript
jquery fancybox ie6不显示关闭按钮的解决办法
Dec 25 Javascript
js如何获取兄弟、父类等节点
Jan 06 Javascript
js实现仿Discuz文本框弹出层效果
Aug 13 Javascript
dedecms页面如何获取会员状态的实例代码
Mar 15 Javascript
详述JavaScript实现继承的几种方式(推荐)
Mar 22 Javascript
深入理解JavaScript中的并行处理
Sep 22 Javascript
浅谈jquery上下滑动的注意事项
Oct 13 Javascript
react native 获取地理位置的方法示例
Aug 28 Javascript
AngularJS实现多级下拉框
Mar 25 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 生成随机验证码图片代码
2010/02/08 PHP
php 实现进制转换(二进制、八进制、十六进制)互相转换实现代码
2010/10/22 PHP
php常用hash加密函数
2014/11/22 PHP
php实现阳历阴历互转的方法
2015/10/28 PHP
详解Yii2.0使用AR联表查询实例
2017/06/16 PHP
jQuery(1.3.2) 7行代码搞定跟随屏幕滚动的层
2009/05/21 Javascript
js动画效果制件让图片组成动画代码分享
2014/01/14 Javascript
js模拟淘宝网的多级选择菜单实现方法
2015/08/18 Javascript
jquery+html5时钟特效代码分享(可设置闹钟并且语音提醒)
2020/03/30 Javascript
自定义刻度jQuery进度条及插件
2015/09/02 Javascript
学习javascript面向对象 理解javascript原型和原型链
2016/01/04 Javascript
Angular2中Bootstrap界面库ng-bootstrap详解
2016/10/18 Javascript
解决浏览器会自动填充密码的问题
2017/04/28 Javascript
Vue实现数字输入框中分割手机号码的示例
2017/10/10 Javascript
javascript 通过键名获取键盘的keyCode方法
2017/12/31 Javascript
微信小程序渲染性能调优小结
2019/07/30 Javascript
vue设置一开始进入的页面教程
2019/10/28 Javascript
Vue前端项目部署IIS的实现
2020/01/06 Javascript
[04:01]2014DOTA2国际邀请赛 TITAN告别Ohaiyo期望明年再战
2014/07/15 DOTA
[01:04:29]DOTA2-DPC中国联赛 正赛 Phoenix vs XG BO3 第二场 1月31日
2021/03/11 DOTA
python实现将汉字转换成汉语拼音的库
2015/05/05 Python
Linux RedHat下安装Python2.7开发环境
2017/05/20 Python
Python中eval带来的潜在风险代码分析
2017/12/11 Python
python的turtle库使用详解
2019/05/10 Python
python网络爬虫 CrawlSpider使用详解
2019/09/27 Python
How TDD works
2012/09/30 面试题
企业精细化管理实施方案
2014/03/23 职场文书
本科毕业生自荐信
2014/06/02 职场文书
群众路线教育查摆剖析材料
2014/10/10 职场文书
先进党支部申报材料
2014/12/24 职场文书
春季运动会开幕词
2015/01/28 职场文书
工商局个人工作总结
2015/03/03 职场文书
导游词之神仙居景区
2019/11/15 职场文书
python unittest单元测试的步骤分析
2021/08/02 Python
yyds什么意思?90后已经听不懂00后讲话了……
2022/02/03 杂记
win10拖拽文件时崩溃怎么解决?win10文件不能拖拽问题解决方法
2022/08/14 数码科技