防抖(Debounce)

一、什么是防抖?


防抖是一种前端常用的优化技术,用于防止连续多次触发事件。从而减少不必要的计算、网络请求或者页面渲染,提高性能。

当一个事件被触发时,防抖函数并不会立即执行,而是会等待一段指定的时间。如果在这段时间内该事件再次被触发,则会取消之前设定的执行计划,并重新开始计时。这样,只有当事件停止触发并经过了预设的时间后,才会真正执行。

通过防抖,可以避免在用户快速连续地进行操作时(例如连续快速点击按钮),服务器或浏览器因为接收到过多无意义的重复请求而造成的性能瓶颈,从而提高页面性能和用户体验。



二、防抖的应用场景

防抖常用于处理短时间内被连续触发多次但并不需要立即响应每一次触发的场景。

  1. 实时搜索:当用户在搜索框中输入内容时,每次输入都会触发 input 事件,频繁发送请求到服务器获取搜索结果,这可能导致用户体验不佳,而且也没有必要。通过防抖,可以确保只有当用户停止输入一段时间后才发起搜索请求。

  2. 窗口大小调整:用户可能快速地调整浏览器窗口大小,导致 resize 事件短时间内被大量触发。如果每次调整都重新计算布局或刷新数据,可能会引起性能问题。防抖能确保在窗口大小稳定后,才执行相关操作。

  3. 表单提交:在多步表单填写场景中,用户可能连续点击“下一步”按钮,而实际上只需要最后一个点击动作有效。应用防抖可以确保最后一次点击后的等待时间过后才进行表单验证和提交操作。

  4. 无限滚动加载更多数据:用户滚动到底部时自动加载更多内容的功能,如果不做防抖处理,可能会在接近底部时由于页面滚动造成的连续触发多次加载请求。通过防抖技术,仅在滚动行为稳定后执行一次加载新数据的操作。

三、代码实现

1.web实现

未使用防抖,当用户鼠标在红色区域移动或者疯狂点击按钮时,事件执行函数会触发多次。如果是向后端发起请求,不仅会造成性能问题,还可能会造成不可预期的错误。

使用防抖代码如下:

每一次触发事件,首先会清除执行函数的定时器,然后重新创建计时器并计时。这样当事件连续触发时,执行函数会不断重新计时,当间隔时间内未再次触发时才会执行,避免了连续多次执行造成的后果。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div style="background: red;width: 500px;height: 500px;" id="box">
    </div>
    <button id="btn">请求</button>
</body>

<script>
    let box = document.querySelector('#box')
    let btn = document.querySelector('#btn')
    let timer
    let timer1
    box.addEventListener('mousemove', () => {
        clearTimeout(timer)
        timer = setTimeout(() => {
            console.log("鼠标移动,发起请求");
        }, 500)
    })
    btn.addEventListener('click', () => {
        clearTimeout(timer1)
        timer1 = setTimeout(() => {
            console.log("点击按钮,发起请求");
        }, 300)

    })
</script>

</html>

2.安卓实现

未防抖,多次点击按钮,事件连续触发多次

使用防抖代码如下:

每次点击按钮时,首先会清除handler的异步任务,然后重新创建延时任务。从而实现防抖。

@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
    val task = Runnable { Log.d("点击", "发起请求 ") }
    val handler = Handler(Looper.getMainLooper())
    Column(
        modifier = modifier.fillMaxSize(),
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Button(onClick = {
            handler.removeCallbacks(task)
            handler.postDelayed(task, 500)
        }) {
            Text(text = name)
        }
    }
}

3.鸿蒙实现

由于Arkts语言基于ts,ts基于js,所以鸿蒙的实现跟web基本相同

@Entry
@Component
struct Message {
  @State message: string = '点击'
  private timer: number

  build() {
    Row() {
      Column() {
        Button(this.message).onClick(() => {
          clearTimeout(this.timer)
          this.timer = setTimeout(() => {
            if (hilog.isLoggable(0x0001, "发起请求", hilog.LogLevel.INFO)) {
              hilog.info(0x0001, "用户", "%{public}s发起请求", this.message)
            }
          }, 350)
        })
      }
      .width('100%')
    }
    .height('100%')
  }
}

  • 24
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
lodash是一个JavaScript工具库,提供了许多实用的函数和工具来简化JavaScript开发。其中之一是`debounce`函数,用于创建一个防抖函数。 防抖函数是指在一定时间内连续触发的事件只执行一次,常用于处理频繁触发的事件,比如浏览器窗口的resize事件、输入框的输入事件等。防抖函数可以避免频繁触发导致的性能问题。 在lodash中,`debounce`函数的用法如下: ```javascript _.debounce(func, wait, options) ``` - `func`:要执行的函数。 - `wait`:等待时间(毫秒),即事件触发后,等待多长时间执行函数。 - `options`:可选参数对象,可以设置更多的选项,比如`leading`和`trailing`。 `leading`和`trailing`是两个布尔值选项: - `leading`:默认为`false`,表示禁用首次执行。如果设置为`true`,则第一次触发事件时立即执行函数。 - `trailing`:默认为`true`,表示在最后一次触发事件后,再等待一段时间执行函数。如果设置为`false`,则最后一次触发事件后不再执行函数。 下面是一个简单的示例,演示如何使用`lodash`的`debounce`函数: ```javascript function saveToServer() { // 模拟发送数据到服务器的操作 console.log("Saving data to server..."); } var debouncedSave = _.debounce(saveToServer, 1000); // 模拟触发事件 debouncedSave(); debouncedSave(); debouncedSave(); // 1秒后,只会执行一次保存操作 ``` 在上述代码中,`saveToServer`函数会被防抖处理,只有在最后一次触发事件后等待1秒后,才会执行一次保存操作。 希望这个例子能够帮助您理解`lodash`中的`debounce`函数。如果您有任何其他问题,请随时提问!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值