加载中...
  • 性能优化:防抖和节流 loading

    debounce防抖


    debounce(f, ms)装饰器的结果是一个包装器,该包装器将暂停对 f 的调用,直到经过 ms 毫秒的非活动状态(没有函数调用,“冷却期”),然后使用最新的参数调用 f 一次。

    换句话说,debounce 就像一个“接听电话”的秘书,并一直等到 ms 毫秒的安静时间之后,才将最新的呼叫信息传达给“老板”(调用实际的 f)。

    举个例子,我们有一个函数 f,并将其替换为 f = debounce(f, 1000)

    然后,如果包装函数分别在 0ms、200ms 和 500ms 时被调用了,之后没有其他调用,那么实际的 f 只会在 1500ms 时被调用一次。也就是说:从最后一次调用开始经过 1000ms 的冷却期之后。

    throttle

    ……并且,它将获得最后一个调用的所有参数,其他调用的参数将被忽略。

    防抖举例


    现在我们举一个实际中的例子。假设用户输入了一些内容,我们想要在用户输入完成时向服务器发送一个请求。

    我们没有必要为每一个字符的输入都发送请求。相反,我们想要等一段时间,然后处理整个结果。

    Web 浏览器中,我们可以设置一个事件处理程序 —— 一个在每次输入内容发生改动时都会调用的函数。通常,监听所有按键输入的事件的处理程序会被调用的非常频繁。但如果我们为这个处理程序做一个 1000msdebounce 处理,它仅会在最后一次输入后的 1000ms 后被调用一次。

    debounce

    看到了吗?第二个输入框调用了防抖函数,所以它的内容是在最后一次输入的 1000ms 后被处理的。

    因此,debounce 是一个处理一系列事件的好方法:无论是系列键盘输入,鼠标移动还是其他类似的事件。

    它在最后一次调用之后等待给定的时间,然后运行其可以处理结果的函数。

    实现一个防抖函数


    1
    2
    3
    4
    5
    6
    7
    function debounce(f, ms) {
    let timeout;
    return function() {
    clearTimeout(timeout);
    timeout = setTimeout(() => f.apply(this, arguments), ms);
    };
    }

    调用 debounce 会返回一个包装器。当它被调用时,它会安排一个在给定的 ms 之后对原始函数的调用,并取消之前的此类超时。

    throttle节流


    当被多次调用时,它会在每 ms 毫秒最多将调用传递给 f 一次。

    与防抖抖的不同是,它是个完全不同的装饰器:

    debounce 会在“冷却”期后运行函数一次。适用于处理最终结果。
    throttle 运行函数的频率不会大于所给定的时间 ms 毫秒。适用于不应该经常进行的定期更新。

    换句话说,throttle 就像接电话的秘书,但是打扰老板(实际调用 f)的频率不能超过每 ms 毫秒一次。

    节流举例


    throttle

    实现一个节流函数


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function throttle(f, ms = 100) {
    let timer = null;
    return function () {
    if (timer) return
    timer = setTimeout(() => {
    f,apply(this, arguments);
    timer = null
    }, ms)
    }
    }

    总结


    防抖:用户输入结束或暂停时,才会触发change事件

    节流:无论输入速度多快,每隔一定时间只会触发一次

    上一篇:
    ES6 的 Proxy
    下一篇:
    JS 实现继承的几种方式
    本文目录
    本文目录