解析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 相关文章推荐
js鼠标左右键 键盘值小结
Jun 11 Javascript
js实现的切换面板实例代码
Jun 17 Javascript
jQuery实现table隔行换色和鼠标经过变色的两种方法
Jun 15 Javascript
node.js中的buffer.toJSON方法使用说明
Dec 14 Javascript
javascript实现类似百度分享功能的方法
Jul 27 Javascript
HTML5 Shiv完美解决IE(IE6/IE7/IE8)不兼容HTML5标签的方法
Nov 25 Javascript
JS触发服务器控件的单击事件(详解)
Aug 06 Javascript
详解Javascript 中的 class、构造函数、工厂函数
Dec 20 Javascript
开发一个Parcel-vue脚手架工具(详细步骤)
Sep 22 Javascript
bootstrap table列和表头对不齐的解决方法
Jul 19 Javascript
Flutter实现仿微信底部菜单栏功能
Sep 18 Javascript
JS中类的静态方法,静态变量,实例方法,实例变量区别与用法实例分析
Mar 14 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的String类代码
2010/04/20 PHP
php+ajax实现带进度条的上传图片功能【附demo源码下载】
2016/09/14 PHP
Laravel 5使用Laravel Excel实现Excel/CSV文件导入导出的功能详解
2017/10/11 PHP
PHP实现的无限分类类库定义与用法示例【基于thinkPHP】
2018/08/06 PHP
Laravel 实现添加多语言提示信息
2019/10/25 PHP
关于js datetime的那点事
2011/11/15 Javascript
js中判断数字\字母\中文的正则表达式 (实例)
2012/06/29 Javascript
JavaScript实现维吉尼亚(Vigenere)密码算法实例
2013/11/22 Javascript
javascript中with()方法的语法格式及使用
2014/08/04 Javascript
Javascript冒泡排序算法详解
2014/12/03 Javascript
鼠标悬停小图标显示大图标
2016/01/22 Javascript
AngularJS基础 ng-mouseenter 指令示例代码
2016/08/02 Javascript
关于数据与后端进行交流匹配(点亮星星)
2016/08/03 Javascript
jQuery实现搜索页面关键字的功能
2017/02/16 Javascript
JavaScript队列的应用实例详解【经典数据结构】
2017/04/12 Javascript
vue弹窗插件实战代码
2018/09/08 Javascript
vue中上传视频或图片或图片和文字一起到后端的解决方法
2019/12/01 Javascript
jQuery+ThinkPHP实现图片上传
2020/07/23 jQuery
五句话帮你轻松搞定js原型链
2020/12/09 Javascript
Python专用方法与迭代机制实例分析
2014/09/15 Python
Python实现的建造者模式示例
2018/08/06 Python
Windows下PyCharm安装图文教程
2018/08/27 Python
Python3爬虫之自动查询天气并实现语音播报
2019/02/21 Python
python爬虫基础教程:requests库(二)代码实例
2019/04/09 Python
jenkins配置python脚本定时任务过程图解
2019/10/29 Python
Python中的__init__作用是什么
2020/06/09 Python
全球虚拟主机商:HostGator
2017/02/06 全球购物
蔻驰西班牙官网:COACH西班牙
2019/01/16 全球购物
将时尚融入珠宝:Adornmonde
2019/10/17 全球购物
接口可以包含哪些成员
2012/09/30 面试题
2014年管理工作总结
2014/11/22 职场文书
高温慰问简报
2015/07/21 职场文书
导游词之青岛崂山
2019/12/27 职场文书
正确使用MySQL INSERT INTO语句
2021/05/26 MySQL
vue-cil之axios的二次封装与proxy反向代理使用说明
2022/04/07 Vue.js
python中filter,map,reduce的作用
2022/06/10 Python