百度面试题:输入框的防抖节流

在之前我写的图片懒加载中提到过防抖节流,随着我更深入的学习发现防抖节流中居然还包含了那么多细节,本文我将以输入框为例给大家讲解其中的奥秘。

防抖节流的意义

通常情况下,输入框都是通过添加一个keyup事件来检测用户输入的内容来实现响应。在没有防抖节流的情况下用户每次按下键盘都会触发事件向服务器发送请求,这不仅容易造成界面响应变慢,也容易出现卡顿,同时也会造成服务器压力过大崩溃的情况。

这是百度搜索的输入框,我发现其中主要使用的还是防抖,在我每一次输入完之后才开始响应。为什么使用防抖比较合适,在下文中我会详细讲解。

案例代码html模块

js 复制代码
<div class="row">
        <div>
            没有节流的input<input type="text" id="inputa">
        </div>
        <div>
            防抖后的input<input type="text" id="inputb">
        </div>
        <div>
            节流后的input<input type="text" id="inputc">
        </div>
    </div>

防抖(Debounce)

原理与目的

防抖技术的核心在于确保一个函数在一段时间内频繁触发后,只执行最后一次。这对于减少不必要的网络请求、避免UI重绘过于频繁非常有效。比如,在输入框中输入关键词时,我们希望用户停止输入一段时间后再发送请求,而不是每次按键都发送请求。

实现思路

  • 闭包:利用闭包保存上一次触发的时间戳和定时器引用。
  • 判断与清除定时器:每次触发时,检查是否有未执行完的定时器,如果有,则清除并重新计时。

简单来说每一次敲击键盘都会触发计时器,如果在delay时间内再次触发,其计时器将会被清除,然后重新计时,直到超过delay使得func(args)执行。如果第一次超过delay时间,再次继续输入该机制依然有效,会在第二次输入超过delay时间后重新执行处理函数。这就是百度输入框使用的方法,输入结束之后发送请求给服务器。(ajax是对keyup的处理函数。)

示例代码

javascript 复制代码
const inputb = document.getElementById('inputb');
//耗时耗性能的任务=>promise 包一下
const ajax = (content) => {
    console.log(`ajax request ${content}`);
        }
const debounce = (func, delay) => {
    let timer=null;
    return (args) => {
        clearTimeout(timer);
        timer = setTimeout(() => {
              func(args);
              }, delay)
          }
     }
        
let debouncedFunc = debounce(ajax, 1000);
inputb.addEventListener('keyup', (e) => {
     let value = e.target.value;
      debouncedFunc(value);
   })

效果展示

节流(Throttle)

原理与目的

与防抖不同,节流保证一个函数在规定时间内至少执行一次,且无论在这段时间内触发多少次,都只执行一次。这适用于那些需要限制执行频率但又不能完全忽视连续触发的场景,如滚动事件监听。

实现思路

  • 闭包:同样利用闭包存储上一次执行的时间戳。
  • 判断执行时机:每次触发时,比较当前时间和上一次执行时间,如果超过了指定间隔,则执行函数,并更新上一次执行时间。

简单来说就是当keyup一直在触发时,为实现处理函数每个delay时间执行一次,那就要使得处理函数在刚开始执行一次,记录下时间然后判断,当现在时间达到delay时执行处理函数并更新时间。那么似乎不用处理没有达到delay的情况,但是这样的话只有keyup一直触发的时候才会让处理函数执行,当keyup停止触发无法保证在输入完之后处理函数最后执行一次。那么在小于delay的时间段内不影响节流的机制又保证最后一次触发处理函数,就需要在keyup一直触发时让里面的计时器产生又再下一次触发keyup时清除,当keyup停止触发时,计时器不再清除,delay时间后触发最后一次处理函数。

示例代码

javascript 复制代码
const inputc = document.getElementById('inputc');
//耗时耗性能的任务=>promise 包一下
const ajax = (content) => {
    console.log(`ajax request ${content}`);
}
//节流功能
//定义的时刻
const throttle = (func, delay) => {
    //last 上一次是什么时候执行的
    //deferTimer 定时器id
    let last, deferTimer;//自由变量
    //func,delay
    //才是事件的处理函数
    //定义时,生成时 func,delay func调用时能找到闭包中的自由变量
    return (args) => {
        //当前时间,隐式类型转换
        let now = +new Date();
        if (last && now < last + delay) {
            clearTimeout(deferTimer);
            deferTimer = setTimeout(() => {
                last = now;
                func(args);
            }, delay)
        } else {
            //再次来到这个地方
            last = now//第一时间
            func(args)//先执行一次
        }
    }
}

inputa.addEventListener('keyup', (e) => {
    ajax(e.target.value);
})

let throttledFunc = throttle(ajax, 1000);

性能优化与用户体验

无论是防抖还是节流,都能显著降低客户端与服务器间的通信频率,减轻服务器压力,同时减少不必要的DOM操作或计算,从而提升应用的响应速度和整体性能。在用户界面交互频繁的场景下,合理运用这些技术,可以大幅提升用户体验,减少因频繁操作导致的卡顿现象。

综上所述,防抖和节流是前端开发中不可或缺的性能优化手段,它们通过对函数执行时机的精确控制,有效解决了高频率事件处理中的性能瓶颈,是构建高性能Web应用的重要工具。

相关推荐
并不会1 小时前
常见 CSS 选择器用法
前端·css·学习·html·前端开发·css选择器
悦涵仙子1 小时前
CSS中的变量应用——:root,Sass变量,JavaScript中使用Sass变量
javascript·css·sass
衣乌安、1 小时前
【CSS】居中样式
前端·css·css3
兔老大的胡萝卜1 小时前
ppk谈JavaScript,悟透JavaScript,精通CSS高级Web,JavaScript DOM编程艺术,高性能JavaScript pdf
前端·javascript
低代码布道师1 小时前
CSS的三个重点
前端·css
耶啵奶膘3 小时前
uniapp-是否删除
linux·前端·uni-app
王哈哈^_^4 小时前
【数据集】【YOLO】【目标检测】交通事故识别数据集 8939 张,YOLO道路事故目标检测实战训练教程!
前端·人工智能·深度学习·yolo·目标检测·计算机视觉·pyqt
cs_dn_Jie5 小时前
钉钉 H5 微应用 手机端调试
前端·javascript·vue.js·vue·钉钉
开心工作室_kaic5 小时前
ssm068海鲜自助餐厅系统+vue(论文+源码)_kaic
前端·javascript·vue.js
有梦想的刺儿5 小时前
webWorker基本用法
前端·javascript·vue.js