js 防抖和节流
在浏览器 DOM 事件里面,有一些事件会随着用户的操作不间断触发。比如:重新调整浏览器窗口大小(resize),浏览器页面滚动(scroll),鼠标移动(mousemove),输入框监听(oninput)等。
也就是说用户在触发这些浏览器操作的时候,如果脚本里面绑定了对应的事件处理方法,这个方法就不停的触发。而当事件处理比较复杂的时候浏览器不断执行计算,从而导致浏览器性能降低甚至卡死,影响用户体验。
一、防抖和节流
防抖(debounce)和节流(throttle)是前端开发中常用的性能优化手段,用以控制函数执行的频率,以减少计算资源的使用,提升用户体验。
防抖:指触发事件后,在指定的时间内,若再次触发事件,则重新计算时间。也就是说,你在一段时间内多次触发,我只执行一次。
节流:指连续触发事件时,保证一定时间内只调用一次函数。也就是说,你在一段时间内多次触发,我每段时间只执行一次。
(1)防抖(debounce)
function debounce(fn, wait) { let timeout = null; return function() { if(timeout !== null) clearTimeout(timeout); timeout = setTimeout(fn, wait); } } // 使用 let myDebouncedFunction = debounce(function() { console.log('Debounced!'); }, 250); window.addEventListener('resize', myDebouncedFunction);
(2)节流(throttle)
下面我们就针对这一情况做函数的节流处理
1.利用闭包进行改进
onSearch(e) { this.throttle(this.queryData, 800); }, /** * 函数的节流处理 * @param fn 节流后处理的方法 * @param delay 操作时间1000=1s */ throttle(fn, delay) { var timer = null; return function(){ clearTimeout(timer); timer = setTimeout(() => { fn(); }, delay); } }, queryData(e) { console.log('1111111') },
2.利用函数的私有变量保存tId
onSearch(e) { this.throttle(this.queryData, null, 800, e.detail); }, /** * 函数的节流处理 * @param fn 节流后处理的方法 * @param context 保存this指向,可以传null * @param delay 操作时间1000=1s
*/ throttle(fn, context, delay, text) { clearTimeout(fn.tId); fn.tId = setTimeout(() => { fn.call(context, text); }, delay); }, queryData(e) { console.log('1111111') },
注意:普通页面和组件间可能存在this指向问题,所以需要传context参数