当前位置: 首页 > news >正文

什么是防抖与节流

防抖(Debouncing)与节流(Throttling)

在前端开发中,尤其是在处理用户输入、窗口调整大小、滚动事件等高频率触发的事件时,防抖和节流是两种常用的技术手段。它们可以帮助我们优化性能,减少不必要的计算,提高用户体验。本文将详细介绍防抖和节流的概念、特点、作用,并通过具体例子进行说明。

一、防抖(Debouncing)

定义

防抖是一种编程技术,用于限制函数在短时间内被频繁调用。当一个函数在短时间内被多次调用时,防抖会延迟执行该函数,直到最后一次调用后的一段时间内没有新的调用才会真正执行。如果在这段时间内又有新的调用,则重新计时。

特点
  • 延迟执行:防抖会在最后一次调用后等待一段时间再执行。
  • 减少执行次数:通过延迟执行,可以大大减少函数的执行次数。
  • 适合连续触发的场景:适用于需要在一系列操作结束后才执行的场景,如搜索框输入、窗口调整大小等。
作用
  • 提高性能:减少不必要的计算,避免页面卡顿。
  • 优化用户体验:避免频繁的网络请求或重绘,提升响应速度。
实现

以下是一个简单的防抖函数实现:

function debounce(func, wait) {let timeout;return function() {const context = this;const args = arguments;clearTimeout(timeout);timeout = setTimeout(() => func.apply(context, args), wait);};
}
示例

假设我们在一个搜索框中输入内容时,每次输入都会触发一个网络请求来获取搜索建议。为了减少请求次数,我们可以使用防抖技术。

<input type="text" id="searchInput" placeholder="Search...">
<script>const input = document.getElementById('searchInput');function fetchSuggestions(query) {console.log('Fetching suggestions for:', query);// 模拟网络请求// fetch(`/api/suggestions?query=${query}`)//   .then(response => response.json())//   .then(data => {//     // 处理数据//   });}const debouncedFetch = debounce(fetchSuggestions, 300);input.addEventListener('input', (event) => {const query = event.target.value;debouncedFetch(query);});
</script>

在这个例子中,fetchSuggestions 函数会在用户停止输入 300 毫秒后才被调用,从而减少了不必要的网络请求。

二、节流(Throttling)

定义

节流是一种编程技术,用于限制函数在一定时间内的调用次数。无论函数被调用多少次,在指定的时间间隔内只会执行一次。节流可以确保函数以固定的时间间隔执行。

特点
  • 固定时间间隔执行:节流会在指定的时间间隔内只执行一次函数。
  • 控制执行频率:通过设置时间间隔,可以控制函数的执行频率。
  • 适合频繁触发的场景:适用于需要控制执行频率的场景,如窗口滚动、鼠标移动等。
作用
  • 提高性能:减少不必要的计算,避免页面卡顿。
  • 优化用户体验:避免频繁的网络请求或重绘,提升响应速度。
实现

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

function throttle(func, limit) {let inThrottle;return function() {const context = this;const args = arguments;if (!inThrottle) {func.apply(context, args);inThrottle = true;setTimeout(() => inThrottle = false, limit);}};
}
示例

假设我们在滚动页面时需要实时更新一些数据,但为了避免频繁更新导致性能问题,我们可以使用节流技术。

<div style="height: 2000px; background: linear-gradient(to bottom, #f0f0f0, #c0c0c0);"><div id="scrollInfo">Scroll Position: 0</div>
</div>
<script>const scrollInfo = document.getElementById('scrollInfo');function updateScrollInfo() {const scrollTop = window.pageYOffset || document.documentElement.scrollTop;scrollInfo.textContent = `Scroll Position: ${scrollTop}`;}const throttledUpdate = throttle(updateScrollInfo, 100);window.addEventListener('scroll', throttledUpdate);
</script>

在这个例子中,updateScrollInfo 函数会在每 100 毫秒内最多执行一次,从而减少了不必要的更新操作。

三、防抖与节流的对比

相同点
  • 目的:两者都旨在减少函数的执行次数,提高性能。
  • 应用场景:都适用于高频率触发的事件,如输入、滚动、窗口调整大小等。
不同点
  • 执行时机
    • 防抖:在最后一次调用后等待一段时间再执行。
    • 节流:在指定的时间间隔内只执行一次。
  • 适用场景
    • 防抖:适用于需要在一系列操作结束后才执行的场景。
    • 节流:适用于需要控制执行频率的场景。

四、高级应用

防抖与节流的组合使用

在某些复杂的场景下,可能需要同时使用防抖和节流来达到最佳效果。例如,在一个搜索框中,我们希望在用户停止输入一段时间后才发起请求,但如果用户持续输入,我们也希望每隔一段时间就发起一次请求。

function debounce(func, wait, immediate) {let timeout;return function() {const context = this;const args = arguments;const later = () => {timeout = null;if (!immediate) func.apply(context, args);};const callNow = immediate && !timeout;clearTimeout(timeout);timeout = setTimeout(later, wait);if (callNow) func.apply(context, args);};
}function throttle(func, limit, trailing) {let lastTime = 0;return function() {const context = this;const args = arguments;const now = Date.now();if (now - lastTime >= limit) {func.apply(context, args);lastTime = now;} else if (trailing) {clearTimeout(lastTime);lastTime = setTimeout(() => {lastTime = 0;func.apply(context, args);}, limit - (now - lastTime));}};
}const input = document.getElementById('searchInput');function fetchSuggestions(query) {console.log('Fetching suggestions for:', query);// 模拟网络请求// fetch(`/api/suggestions?query=${query}`)//   .then(response => response.json())//   .then(data => {//     // 处理数据//   });
}const debouncedThrottledFetch = throttle(debounce(fetchSuggestions, 300, true), 1000, true);input.addEventListener('input', (event) => {const query = event.target.value;debouncedThrottledFetch(query);
});

在这个例子中,debouncedThrottledFetch 函数结合了防抖和节流的特点,既能在用户停止输入一段时间后发起请求,也能在用户持续输入时每隔一段时间发起一次请求。

五、实际应用案例

1. 搜索框自动补全

在一个电商网站的搜索框中,用户输入关键词时,系统会自动显示相关的搜索建议。为了减少网络请求次数,可以使用防抖技术。

<input type="text" id="searchInput" placeholder="Search...">
<ul id="suggestions"></ul>
<script>const input = document.getElementById('searchInput');const suggestions = document.getElementById('suggestions');function fetchSuggestions(query) {console.log('Fetching suggestions for:', query);// 模拟网络请求// fetch(`/api/suggestions?query=${query}`)//   .then(response => response.json())//   .then(data => {//     // 显示建议//     suggestions.innerHTML = data.map(item => `<li>${item}</li>`).join('');//   });}const debouncedFetch = debounce(fetchSuggestions, 300);input.addEventListener('input', (event) => {const query = event.target.value;debouncedFetch(query);});
</script>
2. 窗口调整大小

在响应式布局中,当窗口大小发生变化时,需要重新计算布局。为了避免频繁的计算,可以使用节流技术。

<div id="content" style="width: 100%; height: 100vh; background: linear-gradient(to right, #f0f0f0, #c0c0c0);"></div>
<script>const content = document.getElementById('content');function handleResize() {const width = window.innerWidth;const height = window.innerHeight;content.style.fontSize = `${width / 10}px`;content.textContent = `Width: ${width}, Height: ${height}`;}const throttledResize = throttle(handleResize, 100);window.addEventListener('resize', throttledResize);
</script>
3. 滚动加载更多

在无限滚动列表中,当用户滚动到页面底部时,会自动加载更多内容。为了避免频繁的加载请求,可以使用节流技术。

<div id="list" style="height: 2000px; overflow-y: auto;"><div v-for="item in items" :key="item.id" style="height: 100px; border-bottom: 1px solid #ccc;">{{ item.name }}</div>
</div>
<script>const list = document.getElementById('list');const items = [];function loadMore() {console.log('Loading more items...');// 模拟加载更多数据// fetch('/api/items')//   .then(response => response.json())//   .then(data => {//     items.push(...data);//   });}const throttledLoadMore = throttle(loadMore, 500);list.addEventListener('scroll', () => {if (list.scrollTop + list.clientHeight >= list.scrollHeight) {throttledLoadMore();}});
</script>

六、总结

防抖和节流是前端开发中非常实用的技术,能够有效地减少函数的执行次数,提高性能,优化用户体验。防抖适用于需要在一系列操作结束后才执行的场景,而节流适用于需要控制执行频率的场景。通过合理地使用这两种技术,可以显著提升应用的性能和响应速度。希望本文能帮助你更好地理解和掌握防抖与节流的相关知识。

相关文章:

什么是防抖与节流

防抖&#xff08;Debouncing&#xff09;与节流&#xff08;Throttling&#xff09; 在前端开发中&#xff0c;尤其是在处理用户输入、窗口调整大小、滚动事件等高频率触发的事件时&#xff0c;防抖和节流是两种常用的技术手段。它们可以帮助我们优化性能&#xff0c;减少不必…...

springboot vue 开源 会员收银系统 (12)购物车关联服务人员 订单计算提成

前言 完整版演示 http://120.26.95.195/ 开发版演示 http://120.26.95.195:8889/ 在之前的开发进程中&#xff0c;我们完成订单的挂单和取单功能&#xff0c;今天我们完成购物车关联服务人员&#xff0c;用户计算门店服务人员的提成。 1.商品关联服务人员 服务人员可以选择 一…...

FFmpeg 推流给 FreeSWITCH

FFmpeg 推流&#xff0c;貌似不难&#xff0c;网上有很多资料, 接到一个任务&#xff0c;推流给 FreeSWITCH&#xff0c;最开始以为很容易&#xff0c; 实则不然&#xff0c;FreeSWITCH uuid_debug_media <uuid>&#xff0c; 一直没人任何反应 仔细一查&#xff0c;Fr…...

.npmrc文件的用途

.npmrc 文件是 npm&#xff08;Node.js 的包管理工具&#xff09;用于配置项目或用户的设置文件。它可以存储与 npm 相关的配置信息&#xff0c;如注册表地址、认证信息、代理设置、安装路径等。.npmrc 文件可以出现在不同的地方&#xff0c;具有不同的作用范围&#xff0c;通常…...

C++游戏开发入门:如何从零开始实现自己的游戏项目?

成长路上不孤单&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a; 【14后&#x1f60a;///C爱好者&#x1f60a;///持续分享所学&#x1f60a;///如有需要欢迎收藏转发///&#x1f60a;】 今日分享关于C游戏开发的相关内容&#xff01; 关于【…...

Redis设计与实现第16章 -- Sentinel 总结1(初始化、主从服务器获取信息、发送信息、接收信息)

Sentinel是Redis的高可用解决方案&#xff1a;由一个或多个Sentinel实例组成的Sentinel系统可以监视任意多个主服务器&#xff0c;以及这些主服务器属下的所有从服务器&#xff0c;被监视的主服务器进入下线状态时&#xff0c;自动将下线主服务器属下的某个从服务器升级为新的主…...

Windows10+VirtualBox+Ubuntu:安装虚拟机VirtualBox,虚拟机中安装Ubuntu

一、需求 在Windows10系统中&#xff0c;安装虚拟机VirtualBox&#xff0c;VirtualBox中安装Ubuntu桌面版。 二、环境准备 系统环境 Windows10 内存&#xff1a;8G 虚拟化 虚拟机的运行&#xff0c;如果需要Windows系统开启虚拟化&#xff0c;可以通过BIOS设置。 “虚拟…...

Torchtune在AMD GPU上的使用指南:利用多GPU能力进行LLM微调与扩展

Torchtune on AMD GPUs How-To Guide: Fine-tuning and Scaling LLMs with Multi-GPU Power — ROCm Blogs 这篇博客提供了一份详细的使用Torchtune在AMD GPU上微调和扩展大型语言模型&#xff08;LLM&#xff09;的指南。Torchtune 是一个PyTorch库&#xff0c;旨在让您轻松地…...

C底层 函数栈帧

文章目录 一&#xff0c;什么是寄存器 二&#xff0c;栈和帧 前言 我们在学习c语言程序的时候&#xff0c;是不是有很多的疑问&#xff0c;如 1&#xff0c;为什么形参不可以改变实参 2&#xff0c;为什么我们编写程序的时候会出现烫烫烫......这个乱码 3&#xff0c;那些局…...

【模块一】kubernetes容器编排进阶业务容器化案例

Kubernetes 实战案例 Kubernetes实战案例-规划(基于nerdctl buildkitdcontainerd构建容器镜像) 业务容器化优势&#xff1a; ① 提高资源利用率、节约部署IT成本。 ② 提高部署效率&#xff0c;基于kubernetes实现微服务的快速部署与交付、容器的批量调度与秒级启动。 ③…...

可视化建模以及UML期末复习篇----相关软件安装

作为一个过来人&#xff0c;我的建议是别过来。 一、可视化建模 <1>定义: 官方&#xff1a;一种使用图形符号来表示系统结构和行为的建模技术。 我&#xff1a;其实说白了就是把工作流程用图形画出来。懂不&#xff1f; <2>作用: 提高理解和分析复杂系统的能力。促…...

Appflyer记录卸载事件

Appflyer官方文档 1.原理 1.AppsFlyer每天向Firebase Cloud Messaging&#xff08;FCM&#xff09;和 Apple Push Notification Services&#xff08;APNS&#xff09;发送一次API请求。 2.然后FCM和APNS会发送一条静默推送消息&#xff0c;用于判断用户设备上是否仍装有相关应…...

JDK17 AbstractQueuedSynchronizer 二 条件队列

条件队列 同步队列中的线程是为了争抢锁&#xff0c;而条件队列中的线程是主动释放锁&#xff0c;挂起自己&#xff0c;等条件满足时被别的线程唤醒&#xff0c;继续工作。 AQS里只有1个同步队列&#xff0c;但可以有多个等待队列&#xff0c;每个等待队列对应一个ConditionO…...

8 设计模式之简单工厂模式

设计模式是软件开发中的一套通用解决方案&#xff0c;而简单工厂模式则是最基础、最常用的一种创建型模式。在这篇博客中&#xff0c;我将为大家详细介绍简单工厂模式的概念、优缺点&#xff0c;以及通过一个饮料制作的案例&#xff0c;帮助大家更好地理解和应用这种模式。 一、…...

计算机的错误计算(一百六十九)

摘要 探讨 MATLAB 中一个不动点的计算精度问题。 不动点是一类特殊的循环迭代。它有形式 例1. 已知迭代[1] 计算 显然&#xff0c;每个 均为 0.5 . 下面看看 MATLAB 的计算结果。不妨不用循环语句&#xff0c;直接用算术表达式表示 这时计算结果在如下图片&#xff1a; …...

Android 图形系统之三:SurfaceControl

在 Android 系统中&#xff0c;SurfaceControl 是一个关键的类&#xff0c;用于管理应用窗口和屏幕上的显示内容。它与 SurfaceFlinger 紧密交互&#xff0c;通过 BufferQueue 提供高效的图形缓冲区管理能力。SurfaceControl 是 Android 的显示架构中不可或缺的部分&#xff0c…...

Laravel8.5+微信小程序实现京东商城秒杀方案

一、商品秒杀涉及的知识点 鉴权策略封装掊口访问频次限制小程序设计页面防抖接口调用订单创建事务使用超卖防御 二、订单库存系统方案&#xff08;3种&#xff09; 下单减库存 优点是库存和订单的强一致性&#xff0c;商品不会卖超&#xff0c;但是可能导致恶意下单&#xff…...

Makefile 入门指南:构建自动化编译流程

个人主页&#xff1a;chian-ocean 文章专栏 前言 make 和 Makefile 是编译和构建软件项目时非常常用的工具和文件&#xff0c;它们通常配合使用来自动化项目的编译过程。 make 定义&#xff1a;make 是一个构建自动化工具&#xff0c;用于根据项目文件的依赖关系自动完成编译…...

C#热更原理与HybridCLR

一、Mono的诞生 在Mono之前,C#虽然很好,但是只在windows家族平台上使用,就这点C#与Java就无法比。于是微软公司向ECMA申请将C#作为一种标准。在2001年12月,ECMA发布了ECMA-334 C#语言规范。C#在2003年成为一个ISO标准(ISO/IEC 23270)。意味着只要你遵守CLI(Common Lang…...

里氏替换原则:Java面向对象设计的基石

在面向对象编程&#xff08;OOP&#xff09;中&#xff0c;继承是一个强大的工具&#xff0c;它允许我们创建新的类&#xff08;子类&#xff09;来复用和扩展现有类&#xff08;父类&#xff09;的功能。然而&#xff0c;继承也带来了复杂性&#xff0c;特别是在确保子类能够正…...

【解密LSTM、GRU如何解决传统RNN梯度消失问题】

解密LSTM与GRU&#xff1a;如何让RNN变得更聪明&#xff1f; 在深度学习的世界里&#xff0c;循环神经网络&#xff08;RNN&#xff09;以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而&#xff0c;传统RNN存在的一个严重问题——梯度消失&#…...

【单片机期末】单片机系统设计

主要内容&#xff1a;系统状态机&#xff0c;系统时基&#xff0c;系统需求分析&#xff0c;系统构建&#xff0c;系统状态流图 一、题目要求 二、绘制系统状态流图 题目&#xff1a;根据上述描述绘制系统状态流图&#xff0c;注明状态转移条件及方向。 三、利用定时器产生时…...

LLM基础1_语言模型如何处理文本

基于GitHub项目&#xff1a;https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken&#xff1a;OpenAI开发的专业"分词器" torch&#xff1a;Facebook开发的强力计算引擎&#xff0c;相当于超级计算器 理解词嵌入&#xff1a;给词语画"…...

rnn判断string中第一次出现a的下标

# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...

MySQL 知识小结(一)

一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库&#xff0c;分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷&#xff0c;但是文件存放起来数据比较冗余&#xff0c;用二进制能够更好管理咱们M…...

C# 表达式和运算符(求值顺序)

求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如&#xff0c;已知表达式3*52&#xff0c;依照子表达式的求值顺序&#xff0c;有两种可能的结果&#xff0c;如图9-3所示。 如果乘法先执行&#xff0c;结果是17。如果5…...

Chrome 浏览器前端与客户端双向通信实战

Chrome 前端&#xff08;即页面 JS / Web UI&#xff09;与客户端&#xff08;C 后端&#xff09;的交互机制&#xff0c;是 Chromium 架构中非常核心的一环。下面我将按常见场景&#xff0c;从通道、流程、技术栈几个角度做一套完整的分析&#xff0c;特别适合你这种在分析和改…...

Oracle11g安装包

Oracle 11g安装包 适用于windows系统&#xff0c;64位 下载路径 oracle 11g 安装包...

LCTF液晶可调谐滤波器在多光谱相机捕捉无人机目标检测中的作用

中达瑞和自2005年成立以来&#xff0c;一直在光谱成像领域深度钻研和发展&#xff0c;始终致力于研发高性能、高可靠性的光谱成像相机&#xff0c;为科研院校提供更优的产品和服务。在《低空背景下无人机目标的光谱特征研究及目标检测应用》这篇论文中提到中达瑞和 LCTF 作为多…...

SQL Server 触发器调用存储过程实现发送 HTTP 请求

文章目录 需求分析解决第 1 步:前置条件,启用 OLE 自动化方式 1:使用 SQL 实现启用 OLE 自动化方式 2:Sql Server 2005启动OLE自动化方式 3:Sql Server 2008启动OLE自动化第 2 步:创建存储过程第 3 步:创建触发器扩展 - 如何调试?第 1 步:登录 SQL Server 2008第 2 步…...