前言
有一些浏览器事件可以在很短的事件内快速触发多次,例如 调整窗口大小 或 向下滚动 页面。例如,如果将事件监听器绑定到窗口滚动事件上,并且用户继续非常快速地向下滚动页面,你的事件可能会在3秒的范围内被触发数千次。这可能会导致一些严重的性能问题,
如果在面试中讨论构建应用程序和事件,如滚动、窗口调整大小,或键盘按下的事件时,一定要提及函数防抖动和函数节流来提升页面速度和性能。
直接绑定函数到scroll事件是非常错误的决定,当用户滚动页面时,页面可能会变得非常慢甚至未响应。而函数防抖和函数节流是解决这个问题的一种方式,通过限制需要经过的事件,直至再次调用函数,在处理一些高频率触发的 DOM 事件的时候,它们都能极大提高用户体验。
函数防抖
如果一个事件被频繁触发多次,并且触发的时间间隔过短,则防抖函数可以使得对应的事件处理函数只执行一次
// 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)
}
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。