关闭

原生js实现懒加载并节流

时间: 2019-02-16阅读: 944标签: 性能

像淘宝网站等,页面中有着大量图片,一次性全部加载这些图片会使浏览器发送大量请求和造成浪费。采用懒加载技术,即用户浏览到哪儿,就加载该处的图片。这样节省网络资源、提升用户体验、减少服务器压力。


方法1:使用scrollTop/innerHeight/offsetTop

基本知识点:

window.innerHeight:浏览器可视区域高度
document.body.scrollTop || document.documentElement.scrollTop:浏览器滚动条滚过高度
img.offsetTop:元素距文档顶部的高度 

这里有张图可以非常清晰的理解上述概念:



加载条件:

img.offsetTop < window.innerHeight + document.body.scrollTop;

代码如下:

<script type="text/JavaScript">
	var imgs = document.querySelectorAll('img');
	window.onscroll = function(){
		var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
		var winTop = window.innerHeight;
		for(var i=0;i < imgs.length;i++){
			if(imgs[i].offsetTop < scrollTop + winTop ){
				imgs[i].src = imgs[i].getAttribute('data-src');
			}
		}
	}
</script>

函数节流:

<script type="text/JavaScript">
	var imgs = document.querySelectorAll('img');
	var lazyload = function(){
		var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
		var winTop = window.innerHeight;
		for(var i=0;i < imgs.length;i++){
			if(imgs[i].offsetTop < scrollTop + winTop ){
				imgs[i].src = imgs[i].getAttribute('data-src');
			}
		}
	}
	function throttle(method,delay){
		var timer = null;
		return function(){
			var context = this, args=arguments;
			clearTimeout(timer);
			timer=setTimeout(function(){
				method.apply(context,args);
			},delay);
		}
	}
	window.onscroll = throttle(lazyload,200);
</script>



方法2:使用IntersectionObserver方法

基础知识

var io = new IntersectionObserver(callback, option);
 
//开始观察
io.observe(document.getElementById('example'));
 
//停止观察
io.unobserve(element);
 
// 关闭观察器
io.disconnect();

上面代码中,构造函数IntersectionObserver接收两个参数:callback是可见性变化时的回调函数,option是配置对象(该参数可选)。 这个构造函数的返回值是一个观察器实例。构造函数的返回值是一个观察器实例,实例的observe方法可以指定观察哪个DOM节点。

observe的参数是一个DOM节点对象。如果要观察多个节点,就要多次调用这个方法。 callback函数的参数(entries)是一个数组,每个成员都是一个IntersectionObserverEntry对象。举例来说,如果同时有两个被观察的对象的可见性发生变化,entries数组就会有两个成员。

intersectionRatio:目标元素的可见比例,完全可见时为1,完全不可见时小于等于0。 

 代码如下:

<script type="text/javascript">
	//获取观察器实例  changes是被观察的对象数组
	var observer = new IntersectionObserver(function(changes){  
		console.log(changes);
		changes.forEach(function(index,item){
			if(item.intersectionRatio > 0 && item.intersectionRatio < 1)
				//target:被观察的目标元素,是一个 DOM 节点对象
				item.target.src = item.target.dataset.src;
		});
	});
	function addObserver(){
		var listItems = document.querySelectorAll('.img-item');
		listItems.forEach(function(item){
			//实例的observe方法可以指定观察哪个DOM节点
			//开始观察  observe的参数是一个 DOM 节点对象
			observer.observe(item);
		});
	}
	addObserver();
</script>


完整代码:

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>LozyLoad</title>
	<style>
		.images{
			display: flex;
			flex-direction: column;
			text-align: center;
			width: 500px;
		}
		.img-item{
			height:400px;
			width: 400px;
			margin: 20px;
		}

	</style>
</head>
<body>
	<div class="images">
		<img class="img-item" alt="loading" data-src="./img/img1.png">
		<img class="img-item" alt="loading" data-src="./img/img2.png">
		<img class="img-item" alt="loading" data-src="./img/img3.png">
		<img class="img-item" alt="loading" data-src="./img/img4.png">
		<img class="img-item" alt="loading" data-src="./img/img5.png">
	</div>
	<!--
	<script type="text/javascript">
		//获取观察器实例  changes是被观察的对象数组
		var observer = new IntersectionObserver(function(changes){  
			console.log(changes);
			changes.forEach(function(index,item){
				if(item.intersectionRatio > 0 && item.intersectionRatio < 1)
					//target:被观察的目标元素,是一个 DOM 节点对象
					item.target.src = item.target.dataset.src;
			});
		});
		function addObserver(){
			var listItems = document.querySelectorAll('.img-item');
			listItems.forEach(function(item){
				//实例的observe方法可以指定观察哪个DOM节点
				//开始观察  observe的参数是一个 DOM 节点对象
				observer.observe(item);
			});
		}
		addObserver();
	</script>
	-->
	<script type="text/javascript">
		var imgs = document.querySelectorAll('img');
		var lazyload = function(){
			var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
			var winTop = window.innerHeight;
			for(var i=0;i < imgs.length;i++){
				if(imgs[i].offsetTop < scrollTop + winTop ){
					imgs[i].src = imgs[i].getAttribute('data-src');
				}
			}
		}
		function throttle(method,delay){
			var timer = null;
			return function(){
				var context = this, args=arguments;
				clearTimeout(timer);
				timer=setTimeout(function(){
					method.apply(context,args);
				},delay);
			}
		}
		window.onscroll = throttle(lazyload,200);
	</script>
</body>
</html>



站长推荐

1.云服务推荐: 国内主流云服务商,各类云产品的最新活动,优惠券领取。地址:阿里云腾讯云华为云

2.广告联盟: 整理了目前主流的广告联盟平台,如果你有流量,可以作为参考选择适合你的平台点击进入

链接: http://www.fly63.com/article/detial/2035

关闭

大型php网站性能和并发访问优化方案

网站性能优化对于大型网站来说非常重要,一个网站的访问打开速度影响着用户体验度,网站访问速度慢会造成高跳出率,小网站很好解决,那对于大型网站由于栏目多,图片和图像都比较庞大,那该怎么进行整体性能优化呢

React性能优化整理

通过判断减少数据变化触发的重新渲染, 以及之后的 DOM diff;函数式语言当中, 语言设计允许两个对象一样, 举例 Clojure:;每个函数体当中生成的对象都会有新的引用, useMemo 可以保留一致的引用.

PHP性能优化

性能是网站运行是否良好的关键因素, 网站的性能与效率影响着公司的运营成本及长远发展,编写出高质高效的代码是我们每个开发人员必备的素质,也是我们良好的职业素养。

前端性能的本质是什么?

性能一直以来是前端开发中非常重要的话题。随着前端能做的事情越来越多,浏览器能力被无限放大和利用:从 web 游戏到复杂单页面应用,从 NodeJS 服务到 web VR/AR 和数据可视化,前端工程师总是在突破极限

小程序Canvas性能优化实战

在小程序中使用canvas组件绘制地铁图,地铁图包括地铁线路、站点图标、线及站点名称文字,绘制元素为线、圆、图片、文字。 支持拖动平移和双指缩放。

Netty高性能之道

在IO编程过程中,当需要同时处理多个客户端接入请求时,可以利用多线程或者IO多路复用技术进行处理。Netty的零拷贝主要体现在如下三个方面,随着JVM虚拟机和JIT即时编译技术的发展,对象的分配和回收是个非常轻量级的工作。

Java与Node.js性能PK

如果你打开浏览器,搜索“Java与Node.js哪个更快”,你会发现大部分答案声称Node.js更快,也有一些人持相反意见。Java使用JIT编译器,其性能甚至可以超过C++。在这种情况下,为什么这么多人还是声称Node.js要比Java快呢?

让你的 React 组件跑得再快一点

React 基于虚拟 DOM 和高效 Diff 算法的完美配合,实现了对 DOM 最小粒度的更新。大多数情况下,React 对 DOM 的渲染效率足以我们的业务日常。但在个别复杂业务场景下,性能问题依然会困扰我们。此时需要采取一些措施来提升运行性能

JavaScript最佳实践:性能

该函数可能看上去完全正常,但是它包含了三个对于全局document对象的引用。如果在页面上有多个图片,那么for循环中的document引用就会被执行多次甚至上百次,每次都会要进行作用域链查找

php中一些提高性能的技巧

【概述】* 把类定义成static* echo比print快* 用全等号代替双等,减少类型转换* echo用逗号连接字符串效率高* require比require_once()快,并且尽量不要使用相对路径

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!