图片预加载与图片懒加载(缓载)的区别与实现

本文详细介绍了图片预加载与懒加载的概念及其区别。预加载是在页面加载前加载图片,提升用户体验但增加服务器压力;懒加载则是延时加载,减少不必要的请求,减轻服务器负担。文章还提供了JavaScript实现预加载和懒加载的示例代码,包括利用定时器、条件判断和可视区域监测等方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

预加载与懒加载,我们经常经常用到,这些技术不仅仅限于图片加载,我们今天讨论的是图片加载:

一、什么是图片预加载与懒加载:

图片预加载: 顾名思义,图片预加载就是在网页全部加载之前, 提前加载图片。 当用户需要查看时可直接从本地缓存中渲染, 以提供给用户更好的体验,减少等待的时间。否则,如果一个页面的内容过于庞大,没有使用预加载技术的页面就会长时间的展现为一片空白,这样浏览者可能以为图片预览慢而没兴趣浏览,把网页关掉,这时,就需要图片预加载。 当然这种做法实际上牺牲了服务器的性能换取了更好的用户体验。

图片懒加载(缓载 ): 延迟加载图片或符合某些条件时才加载某些图片。这样做的好处是减少不必要的访问数据库或延迟访问数据库的次数,因为每次访问数据库都是比较耗时的即只有真正使用该对象的数据时才会创建。 懒加载的主要目的是作为服务器前端的优化,减少请求数或延迟请求数。

二、 图片预加载与懒加载的区别:

两者的行为是相反的,一个是提前加载,一个是迟缓甚至不加载。懒加载对服务器前端有一定的缓解压力作用,预载则会增加服务器前端压力。

三、 图片预加载与懒加载 实现:

1、实现 图片预加载:

实现预载的方法非常多,可以用CSS(background)、JS(Image)、HTML(<img />)都可以。常用的是new Image();,设置其src来实现预载,再使用onload方法回调预载完成事件。只要浏览器把图片下载到本地,同样的src就会使用缓存,这是最基本也是最实用的预载方法。当Image下载完图片头后,会得到宽和高,因此可以在预载前得到图片的大小(我所知的方法是用记时器轮循宽高变化)。一般实现预载的工具类,都实现一个Array来存需要预载的URL,然后实现Finish、Error、SizeChange等常用事件,可以由用户选择是顺序预载或假并发预载。Jquery的PreLoad可以用于预载。

<html xmlns="http://www.w3.org/1999/xhtml">
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
		<title>img ready</title>
	</head>
	<body>
		<div>
			<p>
				<button id="testReadyBtn">开始加载图片</button>
				<button id="clsCacheBtn">清空缓存</button>
				<p>(如果图片加载过后,浏览器会缓存)</p>
			</p>
			<div id="status" style="display:none">
				<p><strong>imgReady:</strong>
					<p>
						<p id="statusReady"></p>
						<p><strong>imgLoad:</strong></p>
						<p id="statusLoad">
							<p>
			</div>
			<div id="imgWrap"></div>
			<div style="display:none"></div>
		</div>
	</body>
	<script>
		var imgReady = function(url, callback, error) {
			var width, height, intervalId, check, div, img = new Image(),
				body = document.body;
			img.src = url;
			// 从缓存中读取
			if (img.complete) {
				return callback(img.width, img.height);
			};
			// 通过占位提前获取图片头部数据
			if (body) {
				div = document.createElement('div');
				div.style.cssText = 'visibility:hidden;position:absolute;left:0;top:0;width:1px;height:1px;overflow:hidden';
				div.appendChild(img)
				body.appendChild(div);
				width = img.offsetWidth;
				height = img.offsetHeight;
				check = function() {
					if (img.offsetWidth !== width || img.offsetHeight !== height) {
						clearInterval(intervalId);
						callback(img.offsetWidth, img.clientHeight);
						img.onload = null;
						div.innerHTML = '';
						div.parentNode.removeChild(div);
					};
				};
				intervalId = setInterval(check, 150);
			};
			// 加载完毕后方式获取
			img.onload = function() {
				callback(img.width, img.height);
				img.onload = img.onerror = null;
				clearInterval(intervalId);
				body && img.parentNode.removeChild(img);
			};
			// 图片加载错误
			img.onerror = function() {
				error && error();
				clearInterval(intervalId);
				body && img.parentNode.removeChild(img);
			};
		};
	</script>
	<script>
		/* demo script */
		window.onload = function() {
			var imgUrl = 'https://p1.ssl.qhimg.com/dr/705_705_/t019473cbfb1ccd6dbb.png?size=705x705',
				testReadyBtn = document.getElementById('testReadyBtn'),
				clsCacheBtn = document.getElementById('clsCacheBtn'),
				status = document.getElementById('status'),
				statusReady = document.getElementById('statusReady'),
				statusLoad = document.getElementById('statusLoad'),
				imgWrap = document.getElementById('imgWrap');

			var imgLoad = function(url, callback) {
				var img = new Image();
				img.src = url;
				if (img.complete) {
					callback(img.width, img.height);
				} else {
					img.onload = function() {
						callback(img.width, img.height);
						img.onload = null;
					};
				};

			};
			testReadyBtn.onclick = function() {
				var that = this;
				that.disabled = true;
				status.style.display = 'block';
				statusLoad.innerHTML = statusReady.innerHTML = 'Loading...';
				imgWrap.innerHTML = '<img src="' + imgUrl + '" />';

				// 使用占位方式快速获取大小
				imgReady(imgUrl, function(width, height) {
					statusReady.innerHTML = 'width:' + width + '; height:' + height;
				}, function() {
					statusReady.innerHTML = 'Img Error!';
				});

				// 使用传统方式获取大小
				imgLoad(imgUrl, function(width, height) {
					statusLoad.innerHTML = 'width:' + width + '; height:' + height;
					that.disabled = false;
				}, function() {
					statusLoad.innerHTML = 'Img Error!';
					that.disabled = false;
				});

			};
			clsCacheBtn.onclick = function() {
				imgUrl += new Date().getTime();
				status.style.display = 'none';
				imgWrap.innerHTML = '';
			};
		};
	</script>
</html>

2、 懒加载 实现:

第一种是纯粹的延迟加载,使用setTimeOut或setInterval进行加载延迟,如果用户在加载前就离开了页面,那么就不会加载。 

第二种是条件加载,符合某些条件,或触发了某些事件才开始异步下载。

 第三种是可视区加载,即仅加载用户可以看到的区域,这个主要由监控滚动条来实现,一般会在距用户看到某图片前一定距离遍开始加载,这样能保证用户拉下时正好能看到图片。

Jquery的Lazy Load用于图片缓载

<html>
	<head>
		<meta charset="utf-8" />
		<title>原生Js图片延迟加载</title>
		<style type="text/css">
			* {
				margin: 0;
				padding: 0
			}

			img.scrollLoading {
				border: 1px solid #ccc;
				display: block;
				margin-top: 10px;
			}
		</style>
	</head>
	<body>
		<div id="content">
		</div>
	</body>
</html>
<script type="text/javascript">
	var _CalF = {
		zsl: function(object) { //选择器
			if (object === undefined) return;
			var getArr = function(name, tagName, attr) {
				var tagName = tagName || '*',
					eles = document.getElementsByTagName(tagName),
					clas = (typeof document.body.style.maxHeight === "undefined") ? "className" : "class"; //ie6
				attr = attr || clas,
					Arr = [];
				for (var i = 0; i < eles.length; i++) {
					if (eles[i].getAttribute(attr) == name) {
						Arr.push(eles[i]);
					}
				}
				return Arr;
			};
			if (object.indexOf('#') === 0) { //#id 
				return document.getElementById(object.substring(1));
			} else if (object.indexOf('.') === 0) { //.class
				return getArr(object.substring(1));
			} else if (object.match(/=/g)) { //attr=name
				return getArr(object.substring(object.search(/=/g) + 1), null, object.substring(0, object.search(/=/g)));
			} else if (object.match(/./g)) { //tagName.className
				return getArr(object.split('.')[1], object.split('.')[0]);
			}

		},
		getPosition: function(obj) { //获取元素在页面里的位置和宽高
			var top = 0,
				left = 0,
				width = obj.offsetWidth,
				height = obj.offsetHeight;

			while (obj.offsetParent) {
				top += obj.offsetTop;
				left += obj.offsetLeft;
				obj = obj.offsetParent;
			}
			return {
				"top": top,
				"left": left,
				"width": width,
				"height": height
			};
		}
	};
	//添加图片list
	var _temp = [];

	for (var i = 1; i < 21; i++) {
		_temp.push(
			'<img class="scrollLoading" data-src="https://p1.ssl.qhimg.com/dr/705_705_/t019473cbfb1ccd6dbb.png?size=705x705' +
			i +
			'.jpg" src="http://images.cnitblog.com/blog/150659/201306/23160223-c81dd9aa9a2a4071a47b0ced2c9118bc.gif"  /><br />图片' +
			i);
	}
	_CalF.zsl("#content").innerHTML = _temp.join("");

	function scrollLoad() {
		this.init.apply(this, arguments);
	}

	scrollLoad.prototype = {
		init: function(className) {
			var className = "img." + className,
				imgs = _CalF.zsl(className),
				that = this;
			this.imgs = imgs;
			that.loadImg();
			window.onscroll = function() {
				that.time = setTimeout(function() {
						that.loadImg();
					},
					400);
			}
		},
		loadImg: function() {
			var imgs = this.imgs.reverse(),
				//获取数组翻转
				len = imgs.length;

			if (imgs.length === 0) {
				clearTimeout(this.time);
				return;
			}
			for (var j = len - 1; j >= 0; j--) { //递减
				var img = imgs[j],
					imgTop = _CalF.getPosition(img).top,
					imgSrc = img.getAttribute("data-src"),
					offsetPage = window.pageYOffset ? window.pageYOffset : window.document.documentElement.scrollTop,
					//滚动条的top值
					bodyHeight = document.documentElement.clientHeight; //body的高度
				if ((offsetPage + bodyHeight / 2) > (imgTop - bodyHeight / 2)) {
					img.src = imgSrc;
					this.imgs.splice(j, 1);
				}
			}
		}
	}

	var img1 = new scrollLoad("scrollLoading");
</script>
<!-- 获取屏幕的分辨率 -->
<script type="text/javascript">
	document.write('您的显示器分辨率为:\n' + screen.width + '*' + screen.height + '</br>');
	var ww = document.getElementById("con").offsetWidth,
		w = screen.width / ww,
		h = screen.height / ww,
		r = Math.round(Math.sqrt(w * w + h * h) / 2.54);
	document.write('您的显示器尺寸为:\n' + (screen.width / ww).toFixed(1) + '*' + (screen.height / ww).toFixed(1) + ' cm, ' + r +
		'寸<br/>');
</script>

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值