关闭

原生js实现懒加载并节流

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

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


方法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

关闭

如何从请求、传输、渲染3个方面提升Web前端性能?

什么是WEB前端呢?就是用户电脑的浏览器所做的一切事情。我们来看看用户访问网站,浏览器都做了哪些事情:输入网址 –> 解析域名 -> 请求页面 -> 解析页面并发送页面中的资源请求 -> 渲染资源 -> 输出页面 -> 监听用户操作 -> 重新渲染。

Java与Node.js性能PK

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

React性能优化整理

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

如何将 HTML5 性能发挥到极致

HTML5作为新兴领域越来越热。然而在移动设备硬件性能弱于PC的背景下,对性能的需求显得更为重要,而HTML5性能优化前与优化后有着极大的差别,如何优化才能提高性能,对此熟知的人很少。本文以LayaAir引擎为例

如何优化css expression性能?

IE 浏览器中 CSS Expression 特性的最大的问题:会反复执行,每秒钟可能执行了成百上千次,有严重的性能问题。何对 CSS Expression 进行优化呢?至少:如果我们将 CSS Expression 在匹配的元素中仅执行一次,性能将会提升很大。

怎样测试 JavaScript 的函数性能

通过衡量执行某个函数所花费的时间,以“证明”某些实现比另一些实现更高效始终是一个很好的主意。这也是确保性能在进行一些修改后不受影响并找出瓶颈的好方法。良好的性能有助于获得良好的用户体验。良好的用户体验能够留住用户

Nginx 性能调优实战

Nginx运行工作进程个数一般设置CPU的核心或者核心数x2。如果不了解cpu的核数,可以top命令之后按1看出来,也可以查看/proc/cpuinfo文件 grep ^processor /proc/cpuinfo | wc -l

优化 web 应用程序性能方案总结

在开发 web 应用程序时候,性能都是必不可少的话题。而大部分的前端优化机制都已经被集成到前端打包工具 webpack 中去了,当然,事实上仍旧会有一些有趣的机制可以帮助 web 应用进行性能提升

PHP性能优化总结

在循环中判断时,数值判断使用恒等要比等于高效。在数组中,数组下标是字母时一定要加上单引号或双引号。因为$row[‘id‘]的效率是$row[id]的7倍。尽量不要在for循环中使用函数

前端开发工程师必须关注的几个性能指标

对于一个网站如果希望抓住用户,网站的速度以及稳定性是首当其冲的。从各式各样的前端监控平台中,你都可以获得页面很多的性能指标。本文将介绍几个几个比较关键的指标,并给出相应的优化思路。

点击更多...

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