窗口的resize
、scroll
,输入框内容校验等操做时,若是这些操做处理函数较为复杂或页面频繁重渲染等操做时,若是事件触发的频率无限制,会加剧浏览器的负担,致使用户体验很是糟糕。此时咱们能够采用debounce(防抖)和throttle(节流)的方式来减小触发的频率,同时又不影响实际效果。javascript
debounce(防抖),简单来讲就是防止抖动。html
从上图中咱们能够看到,当持续触发事件时,debounce会合并事件且不会去触发事件,当必定时间内没有触发再这个事件时,才真正去触发事件~ 一块儿来实现个简单的debounce:java
function debounce(fn, delay) { var ctx; var args; var timer = null; var later = function () { fn.apply(ctx, args); // 当事件真正执行后,清空定时器 timer = null; }; return function () { ctx = this; args = arguments; // 当持续触发事件时,若发现事件触发的定时器已设置时,则清除以前的定时器 if (timer) { clearTimeout(timer); timer = null; } // 从新设置事件触发的定时器 timer = setTimeout(later, delay); }; }
效果图:git
throttle(节流),当持续触发事件时,保证隔间时间触发一次事件。github
上图中绿色块表示触发一次事件,持续触发事件时,throttle会合并必定时间内的事件,并在该时间结束时真正去触发一次事件~ 一块儿来看看throttle的简单实现:浏览器
function throttle(fn, delay) { var ctx; var args; // 记录上次触发事件 var previous = Date.now(); var later = function () { fn.apply(ctx, args); }; return function () { ctx = this; args = arguments; var now = Date.now(); // 本次事件触发与上一次的时间比较 var diff = now - previous - delay; // 若是隔间时间超过设定时间,即再次设置事件触发的定时器 if (diff >= 0) { // 更新最近事件触发的时间 previous = now; setTimeout(later, delay); } }; }
效果图:闭包
根据实际业务场景,合理的利用debounce(防抖)和throttle(节流)能够优化性能和提升用户体验。二者间的核心区别就在于持续触发事件时,前者合并事件并在最后时间去触发事件,然后者则是隔间时间触发一次~app
setTimeout 定时器less
w3school函数
ruanyifeng