什么是防抖与节流
防抖(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)中,继承是一个强大的工具,它允许我们创建新的类(子类)来复用和扩展现有类(父类)的功能。然而,继承也带来了复杂性,特别是在确保子类能够正…...
QMC5883L的驱动
简介 本篇文章的代码已经上传到了github上面,开源代码 作为一个电子罗盘模块,我们可以通过I2C从中获取偏航角yaw,相对于六轴陀螺仪的yaw,qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...
鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南
1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发,使用DevEco Studio作为开发工具,采用Java语言实现,包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...
laravel8+vue3.0+element-plus搭建方法
创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...
九天毕昇深度学习平台 | 如何安装库?
pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子: 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...
return this;返回的是谁
一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请,不同级别的经理有不同的审批权限: // 抽象处理者:审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...
BLEU评分:机器翻译质量评估的黄金标准
BLEU评分:机器翻译质量评估的黄金标准 1. 引言 在自然语言处理(NLP)领域,衡量一个机器翻译模型的性能至关重要。BLEU (Bilingual Evaluation Understudy) 作为一种自动化评估指标,自2002年由IBM的Kishore Papineni等人提出以来,…...
Spring AI Chat Memory 实战指南:Local 与 JDBC 存储集成
一个面向 Java 开发者的 Sring-Ai 示例工程项目,该项目是一个 Spring AI 快速入门的样例工程项目,旨在通过一些小的案例展示 Spring AI 框架的核心功能和使用方法。 项目采用模块化设计,每个模块都专注于特定的功能领域,便于学习和…...
uniapp 集成腾讯云 IM 富媒体消息(地理位置/文件)
UniApp 集成腾讯云 IM 富媒体消息全攻略(地理位置/文件) 一、功能实现原理 腾讯云 IM 通过 消息扩展机制 支持富媒体类型,核心实现方式: 标准消息类型:直接使用 SDK 内置类型(文件、图片等)自…...
Linux安全加固:从攻防视角构建系统免疫
Linux安全加固:从攻防视角构建系统免疫 构建坚不可摧的数字堡垒 引言:攻防对抗的新纪元 在日益复杂的网络威胁环境中,Linux系统安全已从被动防御转向主动免疫。2023年全球网络安全报告显示,高级持续性威胁(APT)攻击同比增长65%,平均入侵停留时间缩短至48小时。本章将从…...
Qt的学习(一)
1.什么是Qt Qt特指用来进行桌面应用开发(电脑上写的程序)涉及到的一套技术Qt无法开发网页前端,也不能开发移动应用。 客户端开发的重要任务:编写和用户交互的界面。一般来说和用户交互的界面,有两种典型风格&…...
