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

 更新时间:2016年10月27日 14:36:59   作者:HackerVirus  
本篇文章介绍了javascript图片懒加载与预加载的分析,详细的介绍了懒加载和预加载的问题,有需要的可以了解一下。

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

懒加载也叫延迟加载:前一篇文章有介绍: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可以继续关注本站。

相关文章

  • SOSO地图API使用(一)在地图上画圆实现思路与代码

    SOSO地图API使用(一)在地图上画圆实现思路与代码

    最近在做SOSO地图相关开发,遇到相关画圆知识,特此简单记录下来,接下来讲解如何在在地图上画圆,感兴趣的朋友可以了解下
    2013-01-01
  • javascript 特性检测并非浏览器检测

    javascript 特性检测并非浏览器检测

    NCZ在他的同名博客《Feature detection is not browser detection》中,讲述了一直以来前端开发中的一个热门技术——检测用户的浏览器平台,并详细地叙说历史发展以及各种办法的优缺点。
    2010-01-01
  • js实现单层数组转多层树

    js实现单层数组转多层树

    这篇文章主要介绍了js实现单层数组转多层树方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-06-06
  • JS实现简单拖动模态框案例

    JS实现简单拖动模态框案例

    这篇文章主要为大家详细介绍了JS实现简单拖动模态框案例,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-07-07
  • 微信小程序开发经验总结(推荐)

    微信小程序开发经验总结(推荐)

    本篇文章主要介绍了微信小程序开发经验总结(推荐),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-01-01
  • JS实现汉字与Unicode码相互转换的方法详解

    JS实现汉字与Unicode码相互转换的方法详解

    这篇文章主要介绍了JS实现汉字与Unicode码相互转换的方法,结合实例形式较为详细的分析了javascript针对汉字与Unicode编码转换的操作技巧与相关注意事项,需要的朋友可以参考下
    2017-04-04
  • JavaScript基础入门之错误捕获机制

    JavaScript基础入门之错误捕获机制

    初级开发人员往往很少使用js的抛出和捕获异常,但抛出和捕获异常往往是非常必要的,这篇文章主要给大家介绍了关于JavaScript基础入门之错误捕获机制的相关资料,需要的朋友可以参考下
    2021-08-08
  • js封装成插件_Canvas统计图插件编写实例

    js封装成插件_Canvas统计图插件编写实例

    下面小编就为大家带来一篇js封装成插件_Canvas统计图插件编写实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-09-09
  • JavaScript中 DOM操作方法小结

    JavaScript中 DOM操作方法小结

    本篇文章主要介绍了JavaScript中 DOM操作方法小结,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-04-04
  • 利用Javascript开发一个二维周视图日历

    利用Javascript开发一个二维周视图日历

    这篇文章主要给大家介绍了关于利用Javascript如何开发一个二维周视图日历的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
    2017-12-12

最新评论