有一些浏览器事件能够在很短的事件内快速触发屡次,例如 调整窗口大小 或 向下滚动 页面。例如,若是将事件监听器绑定到窗口滚动事件上,而且用户继续很是快速地向下滚动页面,你的事件可能会在3秒的范围内被触发数千次。这可能会致使一些严重的性能问题,面试
若是在面试中讨论构建应用程序和事件,如滚动、窗口调整大小,或键盘按下的事件时,必定要说起函数防抖动和函数节流来提高页面速度和性能。浏览器
直接绑定函数到scroll事件是很是错误的决定,当用户滚动页面时,页面可能会变得很是慢甚至未响应。而函数防抖和函数节流是解决这个问题的一种方式,经过限制须要通过的事件,直至再次调用函数,在处理一些高频率触发的 DOM 事件的时候,它们都能极大提升用户体验。闭包
若是一个事件被频繁触发屡次,而且触发的时间间隔太短,则防抖函数可使得对应的事件处理函数只执行一次app
// debounce函数用来包裹咱们的事件处理方法 function debounce(fn, delay){ // 持久化一个定时器 let timer = null // 闭包函数能够访问timer return function(){ // 经过 this 和 arguments 得到函数的做用域和参数 let context = this let args = arguments // 若是事件被触发,清除timer并从新开始计时 clearTimeout(timer) timer = setTimeout(function() { fn.apply(context, args) }, delay) } } function foo(){ console.log('You are scrolling!') } document.addEventListener('scroll', debounce(foo, 50));
throttle 的概念理解稍微容易一些,若是一个事件被频繁触发屡次,节流函数能够按照固定频率去执行对应的事件处理方法函数
function throttle(fn, threshold){ var last var timer threshold || (threshold = 250) return function(){ let context = this let args = arguments var now = +new Date() if(last&&now<last+threshold){ clearTimeout(timer) timer = setTimeout(function(){ last = now fn.apply(context, args) },threshold) }else { last = now fn.apply(context, args) } } }