防抖:
在JavaScript中,防抖(Debounce)是一种编程技巧,用于控制某些函数的执行频率,以确保它们不会因为连续的触发(如快速连续的用户输入、窗口调整大小等事件)而在短时间内被频繁调用。防抖的主要目的是优化性能,减少不必要的计算和 DOM 操作,从而提高应用程序的响应速度和用户体验。
用效果展示一下:文章源自灵鲨社区-https://www.0s52.com/bcjc/javascriptjc/15338.html
文章源自灵鲨社区-https://www.0s52.com/bcjc/javascriptjc/15338.html
所以说,不管你是点击还是怎样的轻微触碰,都会使页面上的数字疯狂增加,这就像是我们在执行我们页面上的按钮操作一样,页面上的效果一直在不间断的加载,也就是短时间内被频繁调用,这就影响了操作和用户体验,从而有了防抖这个概念。文章源自灵鲨社区-https://www.0s52.com/bcjc/javascriptjc/15338.html
这里也就是说,dom update < 屏幕更新时间,这就前段问题复杂起来了,在 ajax 发送请求时,耗时的任务 > 触发频率,所以我们在这里来进行前端的性能优化。文章源自灵鲨社区-https://www.0s52.com/bcjc/javascriptjc/15338.html
防抖的功能
- 提高性能:通过减少不必要的函数调用,降低CPU和内存的使用,尤其是在执行开销较大的函数操作时,如DOM操作、网络请求等,能显著提升应用性能。
- 优化用户体验:对于用户输入、窗口大小调整等场景,防抖可以避免因连续快速的操作导致界面卡顿或频繁更新,提供更平滑的用户体验。
- 节省资源:对于需要访问外部资源(如服务器API调用)的操作,防抖可以减少不必要的网络请求,节约带宽和服务器资源。
- 控制事件响应:在某些情况下,我们可能只关心用户操作的最终状态而非中间过程,比如表单验证、搜索建议的显示,防抖可以帮助我们只在用户停止操作后才执行相应的处理逻辑。
- 减少误操作:对于一些敏感操作,防抖可以防止用户因快速连续点击导致的多次执行,如提交按钮的点击。
所以我们最终的目的是:页面的优化,是我们前端性能优化最重要的点。文章源自灵鲨社区-https://www.0s52.com/bcjc/javascriptjc/15338.html
使用防抖带来的效果
xml
<div id="container"></div>
<script>
var count = 1;
var container = document.getElementById('container');
// 事件处理函数
function getUserAction() {
container.innerHTML = count++;
}
function debounce (func,wait) {
// 这就是闭包
var timeout
return function() {
// 事件的执行函数 this -> container
// 控制执行次
var context = this
var args = arguments //
clearTimeout(timeout)
// func this -> 普通函数来运行 window
timeout = setTimeout(function() {
func.apply(context,args)
},wait)
}
}
container.onmousemove = debounce(getUserAction,1000)
</script>
这段代码是一个完整的HTML文档,演示了如何使用原生JavaScript实现一个具有防抖(debounce)功能的鼠标移动跟踪器。下面是代码的详细解释和组成部分:文章源自灵鲨社区-https://www.0s52.com/bcjc/javascriptjc/15338.html
CSS样式
- 内联样式定义了一个ID选择器(
#container
),设置了该div
的样式属性,如宽度、高度、背景色、字体大小等,使其在页面中突出显示,并且文本居中。
JavaScript脚本
- 变量初始化:
count
变量初始化为1,用于存储鼠标移动的次数。container
变量通过document.getElementById('container')
获取页面上的div
元素。
- 事件处理函数
getUserAction
:- 每当该函数被调用时,它会更新
container
的内容为当前的count
值,并使count
自增1。
- 每当该函数被调用时,它会更新
- 防抖函数
debounce
:- 这是一个高阶函数,接收一个函数
func
和等待时间wait
作为参数。 - 它返回一个新的函数,该函数在被连续调用时,只有在最后一次调用后的
wait
毫秒内没有再次被调用时,才会执行传入的func
。 - 使用了闭包来保存上一次的计时器引用,确保每次调用都能清除前一次的定时器,防止函数被执行多次。
- 利用
apply(context, args)
确保在延迟执行时,func
的上下文(this
)是正确的,虽然在这个特定的例子中,由于getUserAction
内部没有直接使用this
,这部分并不关键。
- 这是一个高阶函数,接收一个函数
- 事件绑定:
- 使用DOM Level 0的方式,将
mousemove
事件与container
元素关联,并将debounce
处理后的getUserAction
作为事件处理程序。 - 这意味着当鼠标在
container
内移动时,getUserAction
函数不会立即执行,而是直到鼠标静止超过1000毫秒后,才更新显示计数。
- 使用DOM Level 0的方式,将
这就展示了如何使用JavaScript和防抖技术来提高性能,避免在短时间内因高频触发的事件(如鼠标移动)导致的不必要的函数执行。通过这种方式,页面能够更加高效地响应用户操作,特别是在执行成本较高的操作时。文章源自灵鲨社区-https://www.0s52.com/bcjc/javascriptjc/15338.html
最后需要注意的点是:文章源自灵鲨社区-https://www.0s52.com/bcjc/javascriptjc/15338.html
ini
function getUserAction() {
container.innerHTML = count++;
}
- 事件处理函数的主要目的是更新页面上ID为 container 的元素内容,以反映鼠标移动事件触发的计数,也就是说每当 getUserAction 函数被调用,它就会更新页面上指定 div 的内容,显示自从页面加载以来鼠标在该区域移动的累计次数。
javascript
function debounce (func,wait) {
// 这就是闭包
var timeout
return function() {
// 事件的执行函数 this -> container
// 控制执行次
var context = this
var args = arguments //
clearTimeout(timeout)
// func this -> 普通函数来运行 window
timeout = setTimeout(function() {
func.apply(context,args)
},wait)
}
}
- 在debounce函数下形成了一个function的闭包函数,其能够访问在其外部定义的timeout变量,就使得每次返回的函数实例都有自己的独立
timeout
- 而在之后的时间执行中,分别保存了上下文参数,清除定时器以及设置了新的定时器。而在设置新的定时器中通过apply的显示绑定调用了func函数,改变了this的指向。
惊艳的防抖效果
xml
<body>
<script>
function debounce(func,wait,immediate) {
// 自由变量空间
var timeout ,result
// 真正执行的函数
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) result = func.apply(context,args)
}else {
timeout = setTimeout(function() {
func.apply(context,args)
},wait)
}
return result
}
}
debounce(getUserAction,1000,true)
</script>
</body>
bash
function debounce(func, wait, immediate) { ... }
- func: 需要进行防抖处理的实际函数。
- wait: 防抖的等待时间(毫秒),在此期间若无新的触发,则执行
func
。 - immediate: 布尔值,决定是否立即执行
func
至少一次。
这里最主要的区别就是立即执行的逻辑 immediate。就是说:文章源自灵鲨社区-https://www.0s52.com/bcjc/javascriptjc/15338.html
当immediate
为true
时,检查是否是第一次调用(!timeout
),如果是,则立即执行func
并记录返回结果到result
。同时,设置一个新的定时器,用于重置timeout
,确保后续触发不会立即执行。文章源自灵鲨社区-https://www.0s52.com/bcjc/javascriptjc/15338.html
否则,遵循传统的防抖逻辑,仅在最后一次调用后的wait
毫秒后执行func
。
主体思路:
防抖功能函数 为了性能优化 1/60 (屏幕刷新率) 若是函数执行时间大于屏幕刷新时间 ——> 则会卡顿
func 是真正要执行的处理函数, this,args权利来指向
wait 定时器 id clear ,最后一次的设定
immediate 立即执行一次
总结:
这里最主要的体现就是性能的优化,也是我们前端最主要的点。 debounce将执行推到最后一次,把之前的触发全部取消来减少执行的次数。
评论