常用工具——简单的防抖和节流

防抖和节流

防抖和节流属于开发中常用的两种前端性能优化的技术。其目的是为了防止用户高频的操作某一功能,从而导致频繁发送请求或者造成浏览器的性能下降。

防抖

防抖(Debouncing)的核心原理是在事件发生时设置一个定时器,在指定时间后再执行操作。如果在该时间之前相同事件被触发,则清除之前的定时器并重新设置一个新的定时器,直到指定时间间隔内没有新的事件触发,才会执行最终的操作。这样可以确保操作仅在事件信号稳定后执行一次,从而避免了频繁执行的问题。

举个例子,当我们在搜索框中输入关键词时,输入框会不断触发oninput事件,如果每次输入都需要请求服务器,会造成不必要的请求浪费。此时使用防抖的话,可以实现设置一个规定的时间,在这规定时间内的事件触发不发送请求,只在规定时间结束后请求一次服务器数据,减少了请求次数和服务器的负载。

/**
 * 防抖
 * debounce函数接受func和delay两个参数,其中func是要延迟执行的函数,delay是指定的延迟时间。每当func函数被调用时,它将清除先前设置的定时器,并创建一个新的定时器等待执行。在指定的延迟时间之后,func函数将被执行,传递先前接收到的参数和上下文。
 */
let debounce = (func, delay) => {
  let timer = null; //定时器变量
  return function (...args) {
    //...args rest参数 ES6中引入rest参数(形式为'...变量名'),用于获取函数的多余参数。rest参数之后不能再有其他参数(即只能是最后一个参数)。
    // 对timer进行了闭包,所以timer占据的内存一直存在。timer作为定时器的返回值,里面的数据是一个正整数,表示排队的队列号,默认从1开始,依次递增。
    // clearTimeout(timer)只是让当前这个队列失效,并非清空timer的值,timer中的值还存在。
    clearTimeout(timer);
    // timer = null 清空当前timer中的值。这个可有可无,这里简单记录一下。
    timer = null;
    timer = setTimeout(() => {
      // apply更改this指向
      func.apply(this, args);
    }, delay);
  };
};

节流

节流(Throttling)的核心思想是在指定间隔内只调用一次函数,而忽略其他请求。通过这种方式,可以确保函数仅在特定时间间隔内被调用,从而减少函数的执行次数,并提高应用程序的性能和响应能力。

举个例子,当我们拖动网页上的滚动条时,会不断触发onscroll事件,如果每次触发都去计算滚动距离,会造成浏览器的性能下降。此时使用节流的话,可以实现将一定时间内的多次触发限制为一次操作,只计算一次滚动距离,稀释次数,从而提高用户体验。

/**
 1. 节流
 2. throttle函数接受func和delay两个参数,其中func是要限制频率的函数,delay是指定的时间间隔。每当func函数再次被调用时,如果上一个调用距离现在已经超过了指定间隔,则再次执行func, 否则无视该次调用并返回。
 */
let throttle = (func, delay) => {
  let timer = null; //定时器变量
  return function (...args) {
    // 判断当前是否设置定时器
    if (!timer) {
      timer = setTimeout(() => {
        func.apply(this, args);
        // 清除定时器
        timer = null;
      }, delay);
    }
  };
};
export { debounce, throttle };

闭包

因为防抖和节流都是基于闭包实现的,这里再简单介绍下闭包。

闭包:可以理解为函数嵌套函数,内部函数可以引用外部函数的参数和变量。参数和变量不会被垃圾回收机制回收。

相比较全局变量和局部变量,闭包有两大特点:

1.闭包拥有全局变量的不被释放的特点
2.闭包拥有局部变量的无法被外部访问的特点

闭包的好处:

1.可以让一个变量长期在内存中不被释放
2.避免全局变量的污染,和全局变量不同,闭包中的变量无法被外部使用
3.私有成员的存在,无法被外部调用,只能直接内部调用

摘自https://blog.youkuaiyun.com/happy_kx/article/details/124330489

HTML案例

<!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>防抖和节流</title>
</head>

<body>
    <div>
        防抖:<input id="search" type="text">
    </div>
    <script type="module">
        // 本地HTML页面使用ES6语法,需要在script中配置type="module" 并在vsCode中安装并启动live Server扩展,重启之后右键点击open with live server
        import { debounce, throttle } from "./util/debounceOrThrottle.js"
        // 防抖案例
        let inputDom = document.querySelector('#search');
        let debounceFunc = debounce(getData, 1000);
        inputDom.addEventListener('input', function () {
            debounceFunc('防抖')
        });
        // 获取数据
        function getData(val) {
            console.log('获取数据' + val)
        };
        // 节流案例
        let throttleFunc = throttle(getData, 1000);
        document.addEventListener('click', function () {
            // 传递参数
            throttleFunc('节流')
        })
    </script>
</body>

</html>

本地HTML页面使用es6语法参考https://blog.youkuaiyun.com/cc18868876837/article/details/113915176

这里简单记录下防抖和节流。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值