防抖与节流

前言:

相信学习js的小伙伴们都对防抖与节流的知识点感到并不陌生,小编最近心血来潮整理了一下之前学习js时的笔记,并且阅览了部分网上的资料,梳理了一下这个热门的前端知识点,在复习加深自己的印象的同时也希望能对朋友们有所帮助......

首先,我来介绍一下什么是防抖与节流

  1. 防抖:防抖是指在事件被连续触发时,只执行最后一次触发的操作。当一个事件触发后,如果在指定的时间间隔内再次触发该事件,就会重新计时,直到没有触发事件。防抖常用于优化用户界面的响应,避免因连续触发的事件导致频繁的操作或请求。

  2. 节流:节流是指在一定时间内,控制事件的触发频率,确保在指定时间间隔内只执行一次操作。无论事件触发多频繁,在设定的时间间隔内只会执行一次操作。节流常用于限制某些高频率事件的处理,以控制资源的消耗或减少不必要的重复操作。

  3. 总的来说, 防抖(Debouncing)和节流(Throttling)是用来控制事件触发频率的技术。

撕~,我们为什么需要防抖与节流呢?

其实,防抖和节流的存在是为了解决以下问题:

  1. 控制事件触发频率:有些事件在特定情况下可能会被频繁触发,例如用户输入、页面滚动等。如果没有控制机制,这些频繁触发的事件可能会导致性能问题或不必要的资源消耗。
  2. 优化用户体验:在某些场景下,用户的快速连续操作可能会引起意外的行为或界面闪烁。通过防抖和节流技术,可以限制事件触发的频率,使用户界面更加稳定和可预测,提升用户体验。
  3. 减少不必要的网络请求:在涉及网络请求的场景中,如搜索框输入、自动保存等,频繁的请求可能会增加服务器负载并影响响应速度。通过防抖和节流,可以减少不必要的网络请求次数,优化网络资源的使用。
  4. 减少重复操作:某些操作在短时间内重复执行可能会导致不必要的计算或状态变更。通过防抖和节流,可以限制操作的执行频率,避免重复操作,减少性能消耗。

综上所述,防抖和节流的使用有助于控制事件触发频率、优化用户体验、减少不必要的资源消耗和网络请求,以及避免重复操作,提高应用的性能和可靠性。这些技术在处理高频率事件和性能优化方面发挥着重要作用。

读到这里,可能小伙伴们觉得这些都是纯概念,似乎有一些摸不清头脑,我举一个比较典型的使用场景:相信大家对王者荣耀这款游戏都不陌生吧,其实啊,当我们不断地点击回城嘲讽对手的时候,这就相当于触发了防抖,因为无论你点击回城多少次,每次在你点击的时候,它都会重新开始倒计时,除非你在回城这段时间内没有任何操作,它才会在计时器为0的时候执行回泉水的操作,它限制我们无论执行某个动作多少次,只有最后一次是生效的;而对于节流,小编还是以这个游戏为例,当我们使用了英雄的某个技能之后,这个技能就会进入冷却CD的倒计时,在倒计时这段时间内,我们无法再次触发英雄的这个技能直至CD减少为0,它限制我们在执行了某个动作之后,在特定时间内不能重复执行该动作。

有了上面总体的介绍之后,我来分别介绍一下各自的使用场景和实现的代码样例:

适用于防抖的例子:

  1. 搜索框输入:当用户在搜索框中连续输入时,使用防抖可以延迟发送搜索请求,直到用户停止输入一段时间后才执行搜索操作。
  2. 窗口调整:当窗口大小调整时,使用防抖可以避免在调整过程中频繁触发重排或重绘操作,等到窗口调整完成后再执行相应的操作。
  3. 按钮点击:在某些场景下,按钮的连续点击可能会导致重复操作或不必要的界面刷新。使用防抖可以确保只有在一定时间间隔内执行一次按钮点击操作。

代码样例:

为了对比分析,我先列出没有使用防抖的代码示例和效果
js 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>无防抖</title>
</head>
<body>
    <input type="text" id="searchInput">
    <div id="searchResults"></div>
    <script>
        // 模拟搜索请求的函数
        function sendRequest(query) {
          // 模拟发送搜索请求
          console.log("发送请求的接口被调用了")
        }
    
        // 输入框事件处理函数,无防抖的情况
        const searchInput = document.getElementById('searchInput')
        searchInput.addEventListener('input', function (event) {
          const query = event.target.value
          sendRequest(query) // 每次输入立即执行搜索请求
        });
      </script>
</body>
</html>
</body>
</html>

由上述gif所示,每次输入一个字符时,都会触发一次代码中模拟搜索请求的函数setRequest(query)

现在我给它加入防抖的相关代码:
js 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>有防抖</title>
</head>
<body>
    <input type="text" id="searchInput">
    <div id="searchResults"></div>
  
    <script>
      // 使用防抖的函数
      function debounce(func, delay) {
        let timerId
      
        return () => {
          clearTimeout(timerId)
          timerId = setTimeout(func, delay)
        }
      }
  
      // 模拟搜索请求的函数
      function sendSearch() {
        const query = document.getElementById('searchInput').value
        // 模拟发送搜索请求
        console.log('发送请求的接口被调用了',query)
      }
  
      // 输入框事件处理函数,使用防抖
      const searchInput = document.getElementById('searchInput')
      const debouncedSearch = debounce(sendSearch, 2000)
      searchInput.addEventListener('input', debouncedSearch)
    </script>
</body>
</html>

从上面的gif可以看出,当我连续输入时,不会触发sendSearch()函数,停止输入2秒后就会调用该函数。

适用于节流的例子:

  1. 页面滚动:当用户滚动页面时,使用节流可以限制滚动事件的触发频率,减少处理滚动事件的次数,避免性能问题。
  2. 鼠标移动:当需要对鼠标移动事件进行处理时,使用节流可以限制处理的频率,避免过多的计算或操作。
  3. 自动保存:在编辑文本或表单时,使用节流可以控制自动保存操作的频率,避免密集的保存请求,减少服务器负载。

代码示例:

同样,先举一个没有使用节流的例子:

js 复制代码
<!DOCTYPE html>
<html>
<head>
  <title>无节流</title>
  <style>
    #content {
      height: 2000px;
      background-color: lightgray;
    }
  </style>
</head>
<body>
  <div id="content"></div>

  <script>
    function handleScroll() {
      console.log('页面滚动了')
    }

    window.addEventListener('scroll', handleScroll);
  </script>
</body>
</html>

如上gif所示,只要我拖动页面,它就会触发handleScroll()函数。

现在,我加入节流相关的代码:
js 复制代码
<!DOCTYPE html>
<html>
<head>
  <title>有节流</title>
  <style>
    #content {
      height: 2000px;
      background-color: lightgray;
    }
  </style>
</head>
<body>
    <div id="content"></div>

    <script>
      function throttle(func, delay) {
        let timerId = null
        let isThrottled = false

        function throttled(...args) {
            if (!isThrottled) {
            func(...args)
            isThrottled = true

            timerId = setTimeout(() => {
                isThrottled = false
            }, delay)
            }
        }

        return throttled
    }
  
      function handleScroll() {
        console.log('页面滚动了')
      }
  
      const throttledScroll = throttle(handleScroll, 3000)
  
      window.addEventListener('scroll', throttledScroll)
    </script>
</body>
</html>

加了节流之后,第一次滚动页面会触发一次handleScroll()函数,在接下来的2秒内,无论怎么滚动页面,该函数都不会再次触发,上面的gif展示的不够形象,小伙伴们可以拿小编的代码去测试一下。

最后,小编来总结一下:

当涉及到限制函数在频繁触发的情况下执行的频率时,我们可以使用防抖(debounce)和节流(throttle)这两种技术。

防抖和节流都是为了优化性能和提升用户体验,但它们的实现方式和应用场景有所不同。

防抖(Debounce)的特点和应用场景:

  • 防抖是在一连串连续触发的事件中,只执行最后一次触发的事件。
  • 当事件连续触发时,防抖会等待一段时间(延迟时间),如果在这段时间内没有再次触发事件,那么执行事件处理函数。
  • 如果在延迟时间内又触发了事件,则重新计时,重新等待延迟时间。
  • 防抖常用于处理频繁触发的事件,如输入框输入事件、窗口大小调整事件等。
  • 防抖可以避免过多的计算或操作,减少不必要的函数调用。

节流(Throttle)的特点和应用场景:

  • 节流是在一连串连续触发的事件中,按照一定时间间隔执行事件。
  • 当事件连续触发时,节流会在固定的时间间隔内执行事件处理函数。
  • 无论事件触发频率多高,都会按照固定的时间间隔执行一次事件处理函数。
  • 节流常用于限制函数的执行频率,如滚动事件、鼠标移动事件等。
  • 节流可以控制函数的执行频率,防止过多的计算或操作,提升性能。

总结:

  • 防抖适用于频繁触发的事件,并且只关心最后一次触发的事件。它会等待一定的延迟时间,如果在这段时间内没有再次触发事件,才会执行事件处理函数。
  • 节流适用于频繁触发的事件,并且希望按照一定的时间间隔执行事件处理函数。它会固定地在一定的时间间隔内执行事件处理函数,无论事件触发的频率如何。
  • 防抖和节流都可以减少函数的执行次数,优化性能,提升用户体验。
  • 在选择使用防抖还是节流时,需要根据具体的应用场景和需求来决定。

我的知识点整理到这里就结束啦,感谢朋友们的观看,有错误的地方欢迎在评论区留下您的高见,谢谢!!!

相关推荐
前端郭德纲1 小时前
浅谈React的虚拟DOM
前端·javascript·react.js
2401_879103682 小时前
24.11.10 css
前端·css
ComPDFKit3 小时前
使用 PDF API 合并 PDF 文件
前端·javascript·macos
yqcoder3 小时前
react 中 memo 模块作用
前端·javascript·react.js
优雅永不过时·4 小时前
Three.js 原生 实现 react-three-fiber drei 的 磨砂反射的效果
前端·javascript·react.js·webgl·threejs·three
神夜大侠6 小时前
VUE 实现公告无缝循环滚动
前端·javascript·vue.js
明辉光焱6 小时前
【Electron】Electron Forge如何支持Element plus?
前端·javascript·vue.js·electron·node.js
柯南二号7 小时前
HarmonyOS ArkTS 下拉列表组件
前端·javascript·数据库·harmonyos·arkts
wyy72937 小时前
v-html 富文本中图片使用element-ui image-viewer组件实现预览,并且阻止滚动条
前端·ui·html
前端郭德纲7 小时前
ES6的Iterator 和 for...of 循环
前端·ecmascript·es6