懒加载与预加载的基本概念。javascript
懒加载也叫延迟加载:前一篇文章有介绍:JS图片延迟加载 延迟加载图片或符合某些条件时才加载某些图片。html
预加载:提早加载图片,当用户须要查看时可直接从本地缓存中渲染。前端
两种技术的本质:二者的行为是相反的,一个是提早加载,一个是迟缓甚至不加载。懒加载对服务器前端有必定的缓解压力做用,预加载则会增长服务器前端压力。java
懒加载的意义及实现方式有:浏览器
意义: 懒加载的主要目的是做为服务器前端的优化,减小请求数或延迟请求数。缓存
实现方式: 服务器
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); } }
在google或者火狐下测试 都是正常的 无论我怎么刷新都是正常的,可是在IE6下不是这样的 我点击一下 是正常 再次点击或者从新刷新都不正常。下面的jsfiddle地址:有兴趣的同窗能够试试 点击按钮后 弹出正常结果 再次点击在IE6下就不执行onload里面的方法了,接着从新刷新也不行。
为何其余浏览器正常的:其实缘由很简单,就是浏览器缓存了,除了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);
});