前端防抖与节流一篇讲清楚

防抖(Debounce)和节流(Throttle)是两种常用的优化高频率执行代码的技术。它们主要用于限制函数执行的频率,以避免在短时间内触发大量函数调用导致性能问题。

简单来说,防抖和节流都是用来控制函数执行频率的技术

它们本身不属于任何官方标准或规范,而是一种基于JavaScript(或其它编程语言)实现的"编程技巧"或"设计模式"。 两者核心区别在于 触发频率 和 执行时机

1、防抖

生动比喻: 电梯门 电梯门不会在每个人进来时立刻关闭,而是会等待一段时间(比如5秒)。如果在这5秒内又有人进来,计时器会重置,再等5秒。直到连续5秒内都没有新的人进来,电梯门才会真正关闭并开始运行。 工作原理:

  • 设置一个定时器。

  • 每次触发事件时,都取消之前的定时器,并设置一个新的定时器。

  • 如果在规定的时间间隔内没有再次触发事件,那么定时器中的函数才会被执行。

防抖函数示例

javascript 复制代码
function debounce(func, wait) {
     // 确保只执行一次,通常是最后一次
    // **输入框连续输入,只有在输入完成后才执行搜索**
    let timeoutId;
    
    return function() {
        const context = this;
        const args = arguments;
        clearTimeout(timeout);
        timeoutId = setTimeout(function() {
            func.apply(context, args);
        }, wait);
    };
}

搜索框防抖

ini 复制代码
const searchInput = document.getElementById('search');
const suggestions = document.getElementById('suggestions');

const fetchSuggestions = debounce(async (query) => {
    if (!query.trim()) {
        suggestions.innerHTML = '';
        return;
    }
    
    try {
        const response = await fetch(`/api/suggestions?q=${encodeURIComponent(query)}`);
        const data = await response.json();
        displaySuggestions(data);
    } catch (error) {
        console.error('搜索建议获取失败:', error);
    }
}, 300);

searchInput.addEventListener('input', (e) => {
    fetchSuggestions(e.target.value);
});

function displaySuggestions(items) {
    suggestions.innerHTML = items.map(item => 
        `<div class="suggestion">${item}</div>`
    ).join('');
}

响应式布局调整,窗口调整防抖

scss 复制代码
const handleResize = debounce(() => {
    const width = window.innerWidth;
    
    if (width < 768) {
        // 移动端布局
        adjustMobileLayout();
    } else if (width < 1024) {
        // 平板布局
        adjustTabletLayout();
    } else {
        // 桌面端布局
        adjustDesktopLayout();
    }
}, 250);

window.addEventListener('resize', handleResize);

2、节流

生动比喻: 王者荣耀或者英雄联盟中的技能冷却 一个技能释放后,会进入冷却时间(比如12秒)。在这3秒内,无论你如何疯狂地按技能键,这个技能都不会再次被释放。直到12秒冷却结束,你按下按键,技能才会再次释放并进入下一个冷却周期。 工作原理:

  • 设置一个标志位或记录上一次执行的时间戳。

  • 当事件触发时,检查是否已经过了规定的冷却时间。

  • 如果过了,就执行函数并更新标志位/时间戳;如果没到,就忽略这次触发。

节流函数

ini 复制代码
function throttle(func, wait) {
    // **函数在规定时间内只执行一次,并且每隔规定时间结束后才会执行下一次,不会在规定时间内重复触发**
    // **按钮点击事件,防止重复点击,多次执行**

    let previous = 0;
    return function() {
        const now = Date.now();
        const context = this;
        const args = arguments;
        if (now - previous > wait) {
            func.apply(context, args);
            previous = now;
        }
    };
}

无限滚动加载节流

ini 复制代码
const container = document.getElementById('scroll-container');
let loading = false;

const checkScroll = throttle(() => {
    const { scrollTop, scrollHeight, clientHeight } = container;
    
    // 距离底部100px时加载更多
    if (scrollHeight - scrollTop - clientHeight < 100 && !loading) {
        loading = true;
        loadMoreContent();
    }
}, 200);

container.addEventListener('scroll', checkScroll);

async function loadMoreContent() {
    try {
        const response = await fetch('/api/more-content');
        const data = await response.json();
        appendContent(data);
    } catch (error) {
        console.error('加载失败:', error);
    } finally {
        loading = false;
    }
}

按钮点击节流

ini 复制代码
// 防止重复提交
const submitButton = document.getElementById('submit');
let submitting = false;

const handleSubmit = throttle(async (e) => {
    e.preventDefault();
    
    if (submitting) return;
    
    submitting = true;
    submitButton.disabled = true;
    submitButton.textContent = '提交中...';
    
    try {
        const formData = new FormData(document.getElementById('form'));
        await fetch('/api/submit', {
            method: 'POST',
            body: formData
        });
        alert('提交成功!');
    } catch (error) {
        console.error('提交失败:', error);
        alert('提交失败,请重试');
    } finally {
        submitting = false;
        submitButton.disabled = false;
        submitButton.textContent = '提交';
    }
}, 1000);

submitButton.addEventListener('click', handleSubmit);

最后,前端防抖或者节流本质都是JavaScript的编程技巧,属于JS中的上层武学,掌握它对于编写高质量、高性能的web应用有着重要的作用!!!

相关推荐
kyriewen14 分钟前
Skills 榜前 10 我全装了:只有 3 个能直接用
前端·javascript·程序员
IT_陈寒33 分钟前
当Java的hashCode遇上Lombok,我的缓存被全清了
前端·人工智能·后端
工控丫丫1 小时前
帆软看板中经常使用的公式函数及经常搭的组合
前端·javascript·数据库
jerrywus1 小时前
我用 GPT-6.1-sol 做了台会讲解的 3D 售货机:60 罐饮料,一口没喝上
前端·agent·claude
IT规划师2 小时前
编程术语中的同步与异步:从"等不等"到工程取舍
后端·面试
孟陬3 小时前
Foobar 技术周刊#159:当看不懂代码时,如何高效排障调试。脏页陷阱:一条只读查询,写入数 TB 数据。推测解码:大模型加速利器
前端·人工智能·后端
Zhao-Jichao3 小时前
AI Prompting for Everyone 课程笔记 - P17 图像生成 Imaging Generation
前端
Highcharts.js3 小时前
智能数据分析组件Orbit 正式发布与快速上手体验教程
前端·人工智能·信息可视化·数据分析系统·highcharts·orbit·智能可视化
螺丝钉tina4 小时前
[Playwright ][16]Playwright + TypeScript API 自动化测试实战:API测试
前端·javascript·typescript
小天源5 小时前
智叟云集系统 · 架构与职责分层
服务器·前端·数据库