likes
comments
collection
share

我该怎么优化?防抖?节流?

作者站长头像
站长
· 阅读数 33

节流与防抖是两种用于控制事件触发频率的技术,它们经常用于前端开发中,既不会影响用户的体验,又能优化用户交互和提升浏览器的性能。就比如滚动鼠标和拖动浏览器边界、键盘输入和点击事件来改变窗口大小时,都涉及了节流和防抖。那么它们到底是什么,怎么是实现的呢?

一、节流

技术应用场景

保证在特定的delay时间内,某个功能函数只执行一次。在处理高频触发的事件(如窗口滚动、调整大小、鼠标移动)时特别有用,这些事件在改变的内容很少时,却会高频触发,让浏览器会过度的计算和重绘。

如何实现

<body>
    <div class="row">
        没有节流的input <input type="text" id="inputa">
    </div>
    <div>
        节流后的input <input type="text" id="inputc">
    </div>

    <script>
        const inputa = document.getElementById('inputa')
        const inputc = document.getElementById('inputc')    
        const ajax = (content)=>{
            console.log(`ajax request ${content}`)
        }
        //节流功能  
        const throttle = (func,delay)=>{
            let last,deferTimer //自由变量
            return (args)=>{
                // 当前时间,隐式类型转换
                let now = +new Date()
                if(last && now < last + delay){
                //避免触发
                     clearTimeout(deferTimer)
                     deferTimer = setTimeout(() => {
                        last = now
                     }, delay);
                }else{
                    last = now // 第一次时间
                    func(args) // 先执行一次
                }
            }
        }

        inputa.addEventListener('keyup',(e)=>{
            ajax(e.target.value)
        })
        let throttledFunc = throttle(ajax,1000)
        inputc.addEventListener('keyup',(e)=>{
            let value = e.target.value
            throttledFunc(value)
        })
    </script>
</body>
  • 我们定义ajax函数来模拟耗时性任务,并在控制台打印提示信息来直观观察节流功能。
  • 定义节流函数throttle,返回闭包函数,节流函数中接收要执行的函数与延迟时间,定义自由变量(调用时能找到闭包中的变量):上次函数执行的时间,定时器id。
  • 闭包函数中,第一次调用进入else判断,立即执行func,并在之后的每次调用时(高频事件触发时),如果距离上次执行没有delay时间的话,不会执行func,并且清除定时器,更新当前时间,确保下次距离上次执行没有delay时间时,func依然不会触发。

当用户在输入框中快速输入文字时,使用节流的输入框会有效的减少事件处理器的调用次数,节省了计算资源,提高了用户体验。

我该怎么优化?防抖?节流?

防抖

技术应用场景

确保某个功能函数在一系列的连续触发事件中,只在最后一次事件结束后执行。在处理键盘输入或者点击事件中作用很明显,因为它确保了只有在用户真正停止了操作后才进行逻辑的处理。 Goole Suggest: 当用户在Google搜索框中开始输入查询词时,Google Suggest会预测可能的搜索查询,并实时显示一系列建议供用户选择。

我该怎么优化?防抖?节流?

如何实现

  • 启动json-server模拟后端数据。
    • npm i json-server
    • 创建JSON格式数据作为数据源。创建JSON文件,如db.json
    • 项目目录中打开pack.json,script对象添加脚本。
    • npm run dev(脚本名称) 我该怎么优化?防抖?节流?
我该怎么优化?防抖?节流?
  • 定义debounce函数,接收要防抖处理的函数func,延迟事件delay
  • 返回的闭包函数会清除定时器并重新设定定时器,目的是每次事件触发时都清除掉定时器,不让函数触发,直到在最后一次事件触发调用功能函数(如用户最后一次输入)后,过delay时间,执行func函数。
<body>
    <div>
        没有防抖的input
        <input type="text" 
        id="unDebounce" 
        placeholder="请您要搜索的用户名"
        >
    </div>

    <div>
        防抖后的input
        <input type="text" 
        id="debounce" 
        placeholder="请您要搜索的用户名"
        >
    </div>

    <script>
        // 不加防抖的
        const inputa = document.getElementById('unDebounce')
        const inputb = document.getElementById('debounce')
        function handleNameSearch(e){
            const value = e.target.value
            fetch("http://localhost:3000/users")
            .then(res=>res.json())
            .then(data=>{
                const users = data
                const filterUsers = users.filter(user =>{
                    return user.name.includes(value)
                })
                console.log(filterUsers);
                
            })
        }

        //闭包功能函数
        function debounce(func,delay){
            return function(args){
                clearTimeout(func.id)
                //函数是对象, id挂在func上
                func.id = setTimeout(function(){
                    func(args)
                },delay)
            }
        }
        const debounceNameSearch = debounce(handleNameSearch,500)
        inputa.addEventListener('keyup',handleNameSearch)
        inputb.addEventListener('keyup',debounceNameSearch)
    </script>
</body>

我该怎么优化?防抖?节流?

现在你能在某个场景中正确使用防抖、节流了吗?你该怎么优化类似的功能呢?防抖?节流?

转载自:https://juejin.cn/post/7388338139633352755
评论
请登录