前端性能优化之函数防抖与截流

函数防抖

在前端开发当中,我们都知道有些交互事件,会频繁触发。这样会导致我们的页面渲染性能,如果频繁触发接口调用的话,会直接导致服务器性能的浪费。话不多说,盘它!
在这里插入图片描述

我们先简单列一下

onresize onmousemove onkeydown srcoll onkeyup

这里我是用键盘事件 keyup作为测试

我们先看一段测试用例

<ul>
	<li>
		未做处理: <input type="text" id="ipt">
		<div>函数被调用:<span id="count">0</span></div>
	</li>
</ul>
const oCount = document.getElementById('count');
const oIpt = document.getElementById('ipt');
let init = 0
oIpt.onkeyup = function() { 
	oCount.innerText = ++init
}

看一下输入时候的运行效果。

在这里插入图片描述
我们不难发现,每次输入都会触发事件的执行。如果我们用这样的方式去检测:当前用户输入的用户名是否可用?如此高频率的触发不仅是极大的浪费,而且用户还没有输入完成就检测,对用户的提示也不好。应该等用户输入完了,我们再去触发函数,下面我们优化一下:

// 设置一个默认值 300ms
const oCount2 = document.getElementById('count2');
const oIpt2 = document.getElementById('ipt2');

// 设置一个默认值 300ms
const debounce = (fn, wait = 300) => {
	let time = null
	return function(arguments) {
		const _this = this, args = arguments
		clearTimeout(time)
		time = setTimeout(() => {
			fn.apply(_this, [args])
			// fn.call(_this, args)   //或者使用这个
		}, wait)
	}
}

let init2 = 0
oIpt2.onkeyup = debounce(function() {
	oCount2.innerText = ++init2
}, 500)  //可以自己定义延迟时间间隔

再来看一下比对效果:
在这里插入图片描述
可以看到,加了防抖函数之后,当我们在频繁输入的时候,函数并没有执行, 只有在函数指定的间隔内(500ms)不再输入了,才会执行函数。如果在时间间隔之内继续输入,会触发函数重新计数。

函数防抖的概念:在事件触发后的n秒之后,再去执行真正需要执行的函数,如果在这n秒之内事件又被触发,则重新开始计时

也就是说,如果用户在间隔时间内一直触发函数,那么这个防抖函数内部的真正需要执行的函数将永远无法执行。

那有没有什么好点的办法,让用户在输入过程中,既能触发真实需要的函数,又能达到优化的效果?答案是肯定的,那就是:

函数截流

const oCount3 = document.getElementById('count3');
const oIpt3 = document.getElementById('ipt3');
const oTime = document.getElementById('time');

const throttle = (fn, threshhold = 1000) => {
	let last, deferTimer
	return function(arguments) {
		const _this = this, args = arguments
		let now = +new Date()
		if(last && now < last + threshhold) {
			clearTimeout(deferTimer)
			deferTimer = setTimeout(function () {
          last = now
          fn.call(_this, args)
        }, threshhold)
		} else {
			 last = now
         fn.call(_this, args)
		}
	}
}
let init3 = 0
const throttleIpt = throttle(function() {
	let time = new Date().getMinutes() + ':' + new Date().getSeconds()
	oTime.innerText = time
	oCount3.innerText = ++init3
}, 1000)  // 初始化一下

oIpt3.onkeyup = function() {
	throttleIpt()
}

由于我们设置的时间间隔是1000ms也就是1s。我来看一下优化效果:(注意看调用次数和时间上秒的变化)
在这里插入图片描述
可以看到,任由我们怎么输入,函数会按照我们设定的时间(1s),每秒执行一次。你可以设置更大。

函数截流的概念:规定好一个单位时间,触发函数一次。如果在这个单位时间内触发多次函数的话,只有一次是可被执行的。想执行多次的话,只能等到下一个周期里

他们之间的优缺点,等我下次总结吧!

欢迎大家进群,组队学习!
在这里插入图片描述

发布了47 篇原创文章 · 获赞 61 · 访问量 13万+

猜你喜欢

转载自blog.csdn.net/u011456552/article/details/100715582
今日推荐