什么是防抖与节流
防抖(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>
六、总结
防抖和节流是前端开发中非常实用的技术,能够有效地减少函数的执行次数,提高性能,优化用户体验。防抖适用于需要在一系列操作结束后才执行的场景,而节流适用于需要控制执行频率的场景。通过合理地使用这两种技术,可以显著提升应用的性能和响应速度。希望本文能帮助你更好地理解和掌握防抖与节流的相关知识。
相关文章:
什么是防抖与节流
防抖(Debouncing)与节流(Throttling) 在前端开发中,尤其是在处理用户输入、窗口调整大小、滚动事件等高频率触发的事件时,防抖和节流是两种常用的技术手段。它们可以帮助我们优化性能,减少不必…...
springboot vue 开源 会员收银系统 (12)购物车关联服务人员 订单计算提成
前言 完整版演示 http://120.26.95.195/ 开发版演示 http://120.26.95.195:8889/ 在之前的开发进程中,我们完成订单的挂单和取单功能,今天我们完成购物车关联服务人员,用户计算门店服务人员的提成。 1.商品关联服务人员 服务人员可以选择 一…...
FFmpeg 推流给 FreeSWITCH
FFmpeg 推流,貌似不难,网上有很多资料, 接到一个任务,推流给 FreeSWITCH,最开始以为很容易, 实则不然,FreeSWITCH uuid_debug_media <uuid>, 一直没人任何反应 仔细一查,Fr…...
.npmrc文件的用途
.npmrc 文件是 npm(Node.js 的包管理工具)用于配置项目或用户的设置文件。它可以存储与 npm 相关的配置信息,如注册表地址、认证信息、代理设置、安装路径等。.npmrc 文件可以出现在不同的地方,具有不同的作用范围,通常…...
C++游戏开发入门:如何从零开始实现自己的游戏项目?
成长路上不孤单😊😊😊😊😊😊 【14后😊///C爱好者😊///持续分享所学😊///如有需要欢迎收藏转发///😊】 今日分享关于C游戏开发的相关内容! 关于【…...
Redis设计与实现第16章 -- Sentinel 总结1(初始化、主从服务器获取信息、发送信息、接收信息)
Sentinel是Redis的高可用解决方案:由一个或多个Sentinel实例组成的Sentinel系统可以监视任意多个主服务器,以及这些主服务器属下的所有从服务器,被监视的主服务器进入下线状态时,自动将下线主服务器属下的某个从服务器升级为新的主…...
Windows10+VirtualBox+Ubuntu:安装虚拟机VirtualBox,虚拟机中安装Ubuntu
一、需求 在Windows10系统中,安装虚拟机VirtualBox,VirtualBox中安装Ubuntu桌面版。 二、环境准备 系统环境 Windows10 内存:8G 虚拟化 虚拟机的运行,如果需要Windows系统开启虚拟化,可以通过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上微调和扩展大型语言模型(LLM)的指南。Torchtune 是一个PyTorch库,旨在让您轻松地…...
C底层 函数栈帧
文章目录 一,什么是寄存器 二,栈和帧 前言 我们在学习c语言程序的时候,是不是有很多的疑问,如 1,为什么形参不可以改变实参 2,为什么我们编写程序的时候会出现烫烫烫......这个乱码 3,那些局…...
【模块一】kubernetes容器编排进阶业务容器化案例
Kubernetes 实战案例 Kubernetes实战案例-规划(基于nerdctl buildkitdcontainerd构建容器镜像) 业务容器化优势: ① 提高资源利用率、节约部署IT成本。 ② 提高部署效率,基于kubernetes实现微服务的快速部署与交付、容器的批量调度与秒级启动。 ③…...
可视化建模以及UML期末复习篇----相关软件安装
作为一个过来人,我的建议是别过来。 一、可视化建模 <1>定义: 官方:一种使用图形符号来表示系统结构和行为的建模技术。 我:其实说白了就是把工作流程用图形画出来。懂不? <2>作用: 提高理解和分析复杂系统的能力。促…...
Appflyer记录卸载事件
Appflyer官方文档 1.原理 1.AppsFlyer每天向Firebase Cloud Messaging(FCM)和 Apple Push Notification Services(APNS)发送一次API请求。 2.然后FCM和APNS会发送一条静默推送消息,用于判断用户设备上是否仍装有相关应…...
JDK17 AbstractQueuedSynchronizer 二 条件队列
条件队列 同步队列中的线程是为了争抢锁,而条件队列中的线程是主动释放锁,挂起自己,等条件满足时被别的线程唤醒,继续工作。 AQS里只有1个同步队列,但可以有多个等待队列,每个等待队列对应一个ConditionO…...
8 设计模式之简单工厂模式
设计模式是软件开发中的一套通用解决方案,而简单工厂模式则是最基础、最常用的一种创建型模式。在这篇博客中,我将为大家详细介绍简单工厂模式的概念、优缺点,以及通过一个饮料制作的案例,帮助大家更好地理解和应用这种模式。 一、…...
计算机的错误计算(一百六十九)
摘要 探讨 MATLAB 中一个不动点的计算精度问题。 不动点是一类特殊的循环迭代。它有形式 例1. 已知迭代[1] 计算 显然,每个 均为 0.5 . 下面看看 MATLAB 的计算结果。不妨不用循环语句,直接用算术表达式表示 这时计算结果在如下图片: …...
Android 图形系统之三:SurfaceControl
在 Android 系统中,SurfaceControl 是一个关键的类,用于管理应用窗口和屏幕上的显示内容。它与 SurfaceFlinger 紧密交互,通过 BufferQueue 提供高效的图形缓冲区管理能力。SurfaceControl 是 Android 的显示架构中不可或缺的部分,…...
Laravel8.5+微信小程序实现京东商城秒杀方案
一、商品秒杀涉及的知识点 鉴权策略封装掊口访问频次限制小程序设计页面防抖接口调用订单创建事务使用超卖防御 二、订单库存系统方案(3种) 下单减库存 优点是库存和订单的强一致性,商品不会卖超,但是可能导致恶意下单ÿ…...
Makefile 入门指南:构建自动化编译流程
个人主页:chian-ocean 文章专栏 前言 make 和 Makefile 是编译和构建软件项目时非常常用的工具和文件,它们通常配合使用来自动化项目的编译过程。 make 定义:make 是一个构建自动化工具,用于根据项目文件的依赖关系自动完成编译…...
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面向对象设计的基石
在面向对象编程(OOP)中,继承是一个强大的工具,它允许我们创建新的类(子类)来复用和扩展现有类(父类)的功能。然而,继承也带来了复杂性,特别是在确保子类能够正…...
Vim 调用外部命令学习笔记
Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)
HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...
【Oracle APEX开发小技巧12】
有如下需求: 有一个问题反馈页面,要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据,方便管理员及时处理反馈。 我的方法:直接将逻辑写在SQL中,这样可以直接在页面展示 完整代码: SELECTSF.FE…...
java 实现excel文件转pdf | 无水印 | 无限制
文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...
1.3 VSCode安装与环境配置
进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件,然后打开终端,进入下载文件夹,键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...
页面渲染流程与性能优化
页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...
Ascend NPU上适配Step-Audio模型
1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统,支持多语言对话(如 中文,英文,日语),语音情感(如 开心,悲伤)&#x…...
数据库分批入库
今天在工作中,遇到一个问题,就是分批查询的时候,由于批次过大导致出现了一些问题,一下是问题描述和解决方案: 示例: // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...
深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用
文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么?1.1.2 感知机的工作原理 1.2 感知机的简单应用:基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要: 近期,在使用较新版本的OpenSSH客户端连接老旧SSH服务器时,会遇到 "no matching key exchange method found", "n…...
