前言
前端性能优化经常会用到防抖和节流。
一、常见场景
- input 输入框输入后,自动请求接口
- 监听滚动条事件
- 监听窗口大小改变事件
- 监听鼠标移动事件
- 按钮登录、注册、发送短信等触发事件
- 页面滑到底部加载更多等
二、概念
函数防抖(debounce):高频事件触发后N秒内函数只会执行一次,如果N秒内高频事件再次触发,则重新计算时间。
- 相邻触发间隔不足 n 秒
- 多个
setTimeout
- 从最后一次触发开始计算时间,n 秒后执行函数
- 继续触发,下次函数执行时间未知,可能5n 秒时才再次执行函数,函数执行时间不固定,不具有连续性
函数节流(throttle):高频事件触发,在N秒内只会执行一次,以第一次触发事件计算时间。
- 第一次触发后,就开始计算时间,n 秒后执行函数
- 一个 setTimeout
- n 秒内多次触发,除第一次外其他都无效
- 继续触发,2n 秒后再次执行函数,3n 秒后继续执行函数,函数执行间隔时间固定,具有连续性
三、函数防抖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
/** * 函数防抖 * @param fn 需要执行的函数 * @param wait 延迟执行时间 * @param immediate true:立即执行;false:非立即执行 */ function debounce(fn, wait, immediate) { var timer = null; return function () { var context = this; var args = arguments; timer && clearTimeout(timer); if (immediate) { !timer && fn.apply(context, args); timer = setTimeout(function () { timer = null; }, wait); } else { timer = setTimeout(function () { fn.apply(context, args); }, wait); } }; } |
四、函数节流
1 2 3 4 5 6 7 8 9 10 11 12 13 |
function throttle(fn, wait) { var timer = null; return function () { var context = this; var args = arguments; if (!timer) { timer = setTimeout(function () { fn.apply(context, args); timer = null; }, wait); } }; } |
五、使用lodash
函数
防抖:_.debounce(func, [wait=0], [options=])
节流:_.throttle(func, [wait=0], [options=])