深入理解 JavaScript 防抖与节流:提升性能与用户体验

哈士奇最近在学习js的过程中看到了防抖与节流两个提升性能与用户体验的方法,它也是面试题中的常考知识点,那么如何深入了解防抖与节流呢?哈士奇在这里和大家一起分享哦!

防抖

在前端开发中,我们经常需要处理一些用户触发的事件,比如点击按钮、输入框输入等。然而,如果这些事件触发得过于频繁,可能会导致性能问题和不必要的资源浪费。JavaScript 防抖是一种优化技术,通过延迟执行函数,有效地减少函数调用的频率,提升性能和用户体验。

什么是防抖?

防抖是一种控制函数执行频率的技术。它的基本思想是当一个函数被触发后,不立即执行,而是等待一段时间,如果在这段时间内没有再次触发,那么函数就会被执行。如果在等待时间内再次触发,等待时间将被重新计算,函数的执行时机将被推迟。

防抖的应用场景

  1. 输入框输入事件: 在处理用户输入时,防抖可以确保只在用户停止输入一段时间后才进行处理,避免频繁的请求或操作。

  2. 按钮点击事件: 防抖可以用于按钮点击事件,确保用户点击按钮后只有在一定时间内的第一次点击生效,防止误操作。

  3. 滚动事件: 在处理页面滚动事件时,防抖可以减少触发频率,提高性能。

防抖的实现

让我们来看一段简单的 JavaScript 代码,实现了一个基础的防抖函数:

html 复制代码
<body>
<input type="submit" id="btn">
</body>
javascript 复制代码
let btn = document.getElementById('btn')//获取点击事件
    function send(e){//定义函数确认提交完成
        console.log('已提交',e)
    }
    btn.addEventListener('click',debounce(send,1000))//建立一个监听事件,点击btn后自动运行debounce
    function debounce(fn,deplay){
        let timer=null;//初始化计时器
        return function(){
            let args=arguments;// 对象是一个类数组对象,可以通过索引访问其中的参数。
            if(timer){
                clearTimeout(timer); //检测之前是否有点击过,如果点击过就不提交,重置timer值
            }
            timer=setTimeout(function(){//
                fn.call(this,args)//使用call函数重定位this指针与传入参数
            },deplay)
        }
    }

在这个例子中,debounce 函数接受一个函数 fn 和一个延迟时间 delay,返回一个新的函数,这个新函数在被调用时会启动计时器,确保函数在一段时间内只执行一次。

注意!!!!!

在这里要给大家解释清楚为什么要使用call()方法进行传递this指针重定向和参数传递 如果在这里不加入call()方法进行参数传递的话,根据this指针的指向,我们可以知道fn(方法)指针指向的是全局变量,但是对于btn的监听事件debounce()指针应该指向btn才能接收btn的数值,包括传参也需要传递的是btn的参数。

这里是call()方法的说明文档

优化防抖函数

有时候我们希望在第一次触发事件时立即执行函数,这可以通过添加一个参数来实现:

javascript 复制代码
function debounce(fn, delay, immediate) {
    let timer = null;
    return function() {
        let args = arguments;
        if (immediate && !timer) {
            fn.call(this, args);
        }
        if (timer) {
            clearTimeout(timer);
        }
        timer = setTimeout(function() {
            fn.call(this, args);
        }, delay);
    };
}

通过设置 immediatetrue,可以在第一次触发时立即执行函数。

节流

在前端开发中,频繁触发的事件(如按钮点击、滚动、输入)可能导致性能问题和用户体验下降。JavaScript 节流是一种优化技术,通过控制函数执行的频率,降低触发次数,提升性能和用户交互体验。

什么是节流?

节流是一种控制函数执行频率的技术,确保函数在一定时间内只执行一次。它与防抖不同,防抖是在一定时间内只执行最后一次触发的函数,而节流是在一定时间内按照固定频率执行函数。

节流的应用场景

  1. 按钮点击事件: 节流可以用于按钮点击事件,确保用户点击按钮后只有在一定时间内的第一次点击生效,防止误操作。

  2. 输入框输入事件: 在处理用户输入时,节流可以确保只在一定时间间隔内执行一次处理函数,避免频繁的请求或操作。

  3. 滚动事件: 节流可以用于处理页面滚动事件,减少触发频率,提高性能。

节流的实现

以下是一个简单的 JavaScript 节流函数的实现:

html 复制代码
<body>
    <button id="btn">提交</button>
</body>
javascript 复制代码
let btn = document.getElementById('btn')//获取事件名
    function send(){//设定提交成功样式
        console.log('提交完成');
    }
    btn.addEventListener('click',throttle(send,1000))//确定监听器
    function throttle(fn,deplay){
        let prevTime= Date.now();//确认点击时间
        return function(){
            if(Date.now()-prevTime>deplay){//当时间间隔大于所选时间时进行操作
                fn.apply(this,...arguments)//重定位this与参数
                prevTime= Date.now()//确定新的点击时间
            }
        }
    }

在这个例子中,throttle 函数接受一个函数 fn 和一个延迟时间 delay,返回一个新的函数,这个新函数会按照固定频率执行传入的函数。

优化节流函数

有时候我们可能希望在一开始就执行一次函数,可以通过添加一个参数来实现:

javascript 复制代码
function throttle(fn, delay, immediate) {
    let prevTime = Date.now();
    return function() {
        if (immediate && !prevTime) {
            fn.apply(this, arguments);
        }
        if (Date.now() - prevTime > delay) {
            fn.apply(this, arguments);
            prevTime = Date.now();
        }
    };
}

通过设置 immediatetrue,可以在一开始就执行一次函数。

结语

JavaScript 防抖与节流是一种强大的性能优化技术,特别适用于处理频繁触发的事件。通过合理运用防抖与节流,我们可以降低函数执行的频率,减轻浏览器的负担,提升用户体验。在实际应用中,根据具体场景选择合适的防抖策略,将有助于提高代码的可维护性和性能。你学会了吗?

相关推荐
代码之光_198010 分钟前
保障性住房管理:SpringBoot技术优势分析
java·spring boot·后端
光影少年12 分钟前
vue2与vue3的全局通信插件,如何实现自定义的插件
前端·javascript·vue.js
ajsbxi16 分钟前
苍穹外卖学习记录
java·笔记·后端·学习·nginx·spring·servlet
Rattenking17 分钟前
React 源码学习01 ---- React.Children.map 的实现与应用
javascript·学习·react.js
颜淡慕潇1 小时前
【K8S问题系列 |1 】Kubernetes 中 NodePort 类型的 Service 无法访问【已解决】
后端·云原生·容器·kubernetes·问题解决
熊的猫1 小时前
JS 中的类型 & 类型判断 & 类型转换
前端·javascript·vue.js·chrome·react.js·前端框架·node.js
尘浮生2 小时前
Java项目实战II基于Spring Boot的光影视频平台(开发文档+数据库+源码)
java·开发语言·数据库·spring boot·后端·maven·intellij-idea
尚学教辅学习资料2 小时前
基于SpringBoot的医药管理系统+LW示例参考
java·spring boot·后端·java毕业设计·医药管理
别拿曾经看以后~3 小时前
【el-form】记一例好用的el-input输入框回车调接口和el-button按钮防重点击
javascript·vue.js·elementui
川石课堂软件测试3 小时前
性能测试|docker容器下搭建JMeter+Grafana+Influxdb监控可视化平台
运维·javascript·深度学习·jmeter·docker·容器·grafana