解析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 相关文章推荐
jquery keypress,keyup,onpropertychange键盘事件
Jun 25 Javascript
用js获取电脑信息(是使用与IE浏览器)
Jan 15 Javascript
js查看一个函数的执行时间实例代码
Sep 12 Javascript
实用又漂亮的BootstrapValidator表单验证插件
May 30 Javascript
JavaScript标准对象_动力节点Java学院整理
Jun 27 Javascript
highcharts 在angular中的使用示例代码
Sep 20 Javascript
高性能的javascript之加载顺序与执行原理篇
Jan 14 Javascript
微信小程序实现登录遮罩效果
Nov 01 Javascript
微信小程序实现商城倒计时
Nov 01 Javascript
前端Vue项目详解--初始化及导航栏
Jun 24 Javascript
springboot+vue+对接支付宝接口+二维码扫描支付功能(沙箱环境)
Oct 15 Javascript
Vue实现购物车基本功能
Nov 08 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
phpMyAdmin下载、安装和使用入门教程
2007/05/31 PHP
mysql 性能的检查和优化方法
2009/06/21 PHP
PHP 5.3新特性命名空间规则解析及高级功能
2010/03/11 PHP
php实现的太平洋时间和北京时间互转的自定义函数分享
2014/08/19 PHP
php将12小时制转换成24小时制的方法
2015/03/31 PHP
php从文件夹随机读取文件的方法
2015/06/01 PHP
php遍历树的常用方法汇总
2015/06/18 PHP
phpinfo无法显示的原因及解决办法
2019/02/15 PHP
jQuery+PHP实现图片上传并提交功能
2020/07/27 PHP
nodejs的10个性能优化技巧
2014/07/15 NodeJs
javascript中setTimeout和setInterval的unref()和ref()用法示例
2014/11/26 Javascript
JQuery限制复选框checkbox可选中个数的方法
2015/04/20 Javascript
分享几种比较简单实用的JavaScript tabel切换
2015/12/31 Javascript
jquery 点击元素后,滚动条滚动至该元素位置的方法
2016/08/05 Javascript
JavaScript定义函数_动力节点Java学院整理
2017/06/27 Javascript
简单实现js进度条加载效果
2020/03/25 Javascript
浅谈Vue 数据响应式原理
2018/05/07 Javascript
VUE中v-on:click事件中获取当前dom元素的代码
2018/08/22 Javascript
LayUI数据接口返回实体封装的例子
2019/09/12 Javascript
[02:43]2014DOTA2国际邀请赛 官方Alliance战队纪录片
2014/07/14 DOTA
[15:39]教你分分钟做大人:龙骑士
2014/10/30 DOTA
python简单实现基于SSL的IRC bot实例
2015/06/15 Python
基础的十进制按位运算总结与在Python中的计算示例
2016/06/28 Python
浅谈Python浅拷贝、深拷贝及引用机制
2016/12/15 Python
python如何定义带参数的装饰器
2018/03/20 Python
Python使用cx_Freeze库生成msi格式安装文件的方法
2018/07/10 Python
Django rest framework工具包简单用法示例
2018/07/20 Python
python 循环读取txt文档 并转换成csv的方法
2018/10/26 Python
python 解决flask 图片在线浏览或者直接下载的问题
2020/01/09 Python
Python实现封装打包自己写的代码,被python import
2020/07/12 Python
调用HTML5的Canvas API绘制图形的快速入门指南
2016/06/17 HTML / CSS
Shopee越南:东南亚与台湾电商平台
2019/02/03 全球购物
澳大利亚珠宝商:Shiels
2019/10/06 全球购物
领导班子在批评与自我批评座谈会上的发言
2014/09/28 职场文书
关于法制教育的宣传语
2015/07/13 职场文书
iPhone13将有八大升级
2021/04/15 数码科技