欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

性能优化:手写防抖和节流以及二者的区别

程序员文章站 2024-01-27 17:05:22
...

防抖(debounce)

防抖(debounce):限制事件被频繁触发。(涉及定时器和闭包)

触发事件时,在一定时间内,若没有再次触发事件,则事件处理函数在时间到达时执行一次;
若在一定时间内,又触发事件,则清除上一次的计时,重新开始计时,直到时间到了再执行函数。

应用:输入框校验,百度搜索出现提示文字功能等

场景:监听输入框,一旦文字变化,即触发keyup事件,则触发change事件,打印出输入框的内容。
防抖效果:用户输入结束或暂停时,才触发change事件。

<input type="text" id="input">
const input = document.getElementById('input')
function change(){
    console.log(input.value)
}
input.addEventListener('keyup', change)

结果:在输入时,输入框的内容高频被打印
性能优化:手写防抖和节流以及二者的区别

手写防抖

const input = document.getElementById('input');
function change(){
    console.log("this:"+this);
    console.log(input.value);
}
// input.addEventListener('keyup', change)

// 手写防抖
function debounce(fn, delay){
    // 声明变量来保存计时,让其作为局部变量保存在内存中,且不被随意访问,借助闭包来实现
    let timer = null
    // 通过return的函数可以来间接访问timer
    return function() {
        // 如果时间期限还没到又触发了,则清除上一个定时器,重新计算时间
        if(timer){
            clearTimeout(timer)
        }
        timer = setTimeout(() => {
            // apply函数会执行fn函数,并改变this指向,此时this:谁调用就指向谁 -> 这里为input
            fn.apply(this, arguments)
            // 执行完后,清空定时器
            timer = null
        }, delay)

        // 也可以简单来:timer = setTimeout(fn, delay),但此时this指向window
    }
}

// 运用防抖
input.addEventListener('keyup', debounce(change, 500))

防抖效果:延迟500毫秒后执行,执行的是最近一次触发的事件处理函数。

性能优化:手写防抖和节流以及二者的区别

节流(throttle)

节流(throttle):限制事件被频繁触发。不管怎么触发,在一定时间内,只执行一次。

应用:获取拖拽盒子位置、scroll滚动条等位置。

场景:拖拽一个元素,随时获取该元素被拖拽的位置。

<div id="div" draggable="true">拖拽盒子</div>
const div = document.getElementById('div')
div.addEventListener('drag', function(e) {
    console.log(e.offsetX, e.offsetY)
})

效果:事件会频繁触发,容易导致卡顿。性能优化:手写防抖和节流以及二者的区别

手写节流

const div = document.getElementById('div')
// div.addEventListener('drag', function(e) {
//     console.log(e.offsetX, e.offsetY)
// })

// 手写节流
function throttle(fn, delay) {
    let timer = null
    return function () {
        // 每次触发事件时,如果当前有等待执行的函数,则直接return
        if(timer){
            return
        }
        timer = setTimeout(() => {
            fn.apply(this, arguments)
            // 执行完之后,清空定时器
            timer = null
        }, delay)
    }
}

// 运用节流
div.addEventListener('drag', throttle(function(e) {
    console.log(e.offsetX, e.offsetY)
}, 500))

节流效果:不管触发几次事件,事件处理函数在500毫秒内只会执行一次,执行的是该时间内第一次触发的事件处理函数。

性能优化:手写防抖和节流以及二者的区别

防抖和节流的区别

防抖是将一定时间内的多次执行变成最后一次执行(需要重新计算时间),
而节流是将每隔一段时间的多次执行变成一次执行(不重新计时)。

上一篇: 接入钉钉API发送企业消息

下一篇: