0 Like
防抖和节流
防抖和节流是 JavaScript 开发中性能优化的重要方案, 下面通过代码教你掌握他们.
防抖
当持续触发事件时,一定时间段内没有再触发事件,事件处理函数才会执行一次,如果设定的时间到来之前,又一次触发了事件,就重新开始延时。
function debounce(fun, delay) { let timer = null; return function(args) { let that = this; let _args = args; clearTimeout(timer); timer = setTimeout(function() { fun.call(that, _args); }, delay); }; }
立即防抖和非立即防抖
非立即执行防抖是触发事件后函数不会立即执行,而是在 n 秒后执行,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。
立即执行防抖是触发事件后函数会立即执行,然后 n 秒内不触发事件才能继续执行函数的效果。
下面是一个综合版的例子。
function debounce(func, wait, immediate) { var timeout; return function() { var context = this; var args = arguments; if (timeout) clearTimeout(timeout); if (immediate) { var callNow = !timeout; timeout = setTimeout(function() { timeout = null; }, wait); if (callNow) func.apply(context, args); } else { timeout = setTimeout(function() { func.apply(context, args); }, wait); } }; }
使用场景
-
search 搜索联想,用户在不断输入值时,用防抖来节约请求资源
-
window 触发 resize 的时候,不断的调整浏览器窗口大小会不断的触发这个事件,用防抖来让其只触发一次
节流
当持续触发事件时,保证一定时间段内只调用一次事件处理函数。
function throttle(fn, delay) { let canRun = true; return function() { if (!canRun) { return; } canRun = false; setTimeout(() => { fn.call(this, arguments); canRun = true; }, delay); }; }
节流分为时间戳版和定时器版,下面是一个综合版。
function throttle(func, delay) { var timer = null; var startTime = Date.now(); return function() { var curTime = Date.now(); var remaining = delay - (curTime - startTime); var context = this; var args = arguments; clearTimeout(timer); if (remaining <= 0) { func.apply(context, args); startTime = Date.now(); } else { timer = setTimeout(func, remaining); } }; }
使用场景
-
鼠标不断点击触发,mousedown(单位时间内只触发一次)
-
监听滚动事件,比如是否滑到底部自动加载更多,用 throttle 来判断
参考
PREVIOUS POST
剖析 requestAnimationFrame
NEXT POST
回到顶部的几种玩法