js性能优化之防抖与节流

防抖

函数防抖(debounce):当持续触发事件时,必定时间段内没有再触发事件,事件处理函数才会执行一次,若是设定的时间到来以前,又一次触发了事件,就从新开始延时。javascript

节流

函数节流(throttle):当持续触发事件时,保证必定时间段内只调用一次时间处理函数。css

节流的定义应该比较好理解,举例来讲就是,你在疯狂点击短视频里面的“点亮红心”按钮,好比你10s点击了1000次,可是节流的作法就是在这1000次的事件触发过程当中,我规定1s才能真正的触发红心亮起的逻辑。因此10s内再快的点击频率,也只会亮起10颗红心。html

防抖的定义看起来比较绕,咱们也举例说明。举例某宝或者某东的联想搜索框,正常状况,若是你短期内不停的敲击键盘那么每一次输入的内容都会发送请求给服务端作联想算法,而后不停返回数据,那么下拉框看起来就会不停闪动,体验不好,而且实际上不须要那么高频率的去发送请求,应该是当你中止了一个字或者一个词或者一句话的输入后再发送请求。因此防抖的作法,就是不管你多快的输入(触发事件),我只在这个周期的开始或者结束触发一次事件中的逻辑。如此反复,视为防抖。java

防抖的应用场景

  • search搜索联想,用户不短输入,用防抖节约请求资源,优化用户体验
  • window触发resize的时候,不断调整浏览器窗口大小会触发这个事件,利用防抖来让其触发一次
  • 防止短期内重复提交

节流的应用场景

  • 鼠标不短触发mousedown或者mouseover事件的时候,能够利用节流在单位事件内只触发一次
  • 监听滚动事件,好比是否滑到底部加载更多数据,用节流来判断

防抖的实现

咱们设定一个场景,有一个拥有固定宽高的div,监听这个div的mouseover事件,触发一次就+1,并将值填充到div中。 算法

防抖的目的就是为了让鼠标移动的时候,按照规定的周期结束或者开始的时候才触发这个+1的逻辑。

<html>
<head>
	<title></title>
	<style type="text/css">
	#container{
		width: 400px;
		height: 400px;
		background-color: #333333;
		color:#ffffff;
		display: flex;
		justify-content: center;
		align-items: center;
		font-size: 34px;
		font-weight: 600;
	}
</style>
</head>
<body>
	<div id="container"></div>
	<script type="text/javascript">
		var count = 1;
		var container = document.getElementById('container');
		function getUserAction(){
			this.innerHTML = count++;
		}
		container.onmousemove = debounce(getUserAction,100,false);
		function debounce(fn,wait,flag){
			var timeout;
			return function(){
				var self = this;
				clearTimeout(timeout);

				if(flag){
					var callNow = !timeout;
					timeout = setTimeout(function(){
						timeout = null;
					}, wait);

					if(callNow){
						fn.apply(self);
					}
				}else{
					timeout = setTimeout(function(){
						fn.apply(self);
					}, wait);
				}
			}
		}
	</script>
</body>
</html>
复制代码

节流的实现

继续引用上述场景,节流的目的是为了在鼠标移动不停触发mouseover的时候,+1的逻辑只在规定的周内执行一次(例:鼠标疯狂滑动,只在1s内+1,不会在1s中内触发两次函数)浏览器

<html>
<head>
	<title></title>
	<style type="text/css">
	#container{
		width: 400px;
		height: 400px;
		background-color: #333333;
		color:#ffffff;
		display: flex;
		justify-content: center;
		align-items: center;
		font-size: 34px;
		font-weight: 600;
	}
</style>
</head>
<body>
	<div id="container"></div>
	<script type="text/javascript">
		var count = 1;
		var container = document.getElementById('container');
		function getUserAction(){
			this.innerHTML = count++;
		}
		container.onmousemove = throttle(getUserAction,1000);
		//代理模式
		function throttle(fn,wait){
			var pre = 0;
			return function(){
				var self = this;
				var now =  +new Date();
				if(now-pre>wait){
					fn.apply(self);
					pre = now;
				}
			}
		}
	</script>
</body>
</html>
复制代码
相关文章
相关标签/搜索