前端性能优化:防抖与节流
一、防抖和节流主要是干什么的
防抖和节流主要用于控制函数执行的频率,通过限制函数的触发次数,避免函数被过度调用而引发的性能问题或产生不必要的副作用。
二、防抖
防抖是什么:
1、对于在事件被触发 n 秒后再执行的回调 --> 延迟执行
2、如果在这 n 秒内再次触发事件,重新开始计时
防抖的场景:
1、ajax 请求数据 / 提交数据(下拉刷新)
2、输入验证
注意:防抖有两种场景,一种是上来就要执行一次,一种是在规定的时间后去执行
具体实现:
// 第一种写法:普通写法
// 在执行事件之后,不会立即执行,而是等到定时器时间结束之后才开始执行
/*** * @param {*} func 需要执行的函数* @param {*} delay 延迟执行的时间* @returns */
function debounce(func, delay) {let timer = nullreturn function() {clearTimeout(timer)var self = thisargu = argumentstimer = setTimeout(function() {func.apply(self, argu)}, delay);}
}
/*** 使用 setTimeout 实现防抖。* 在函数被调用时,清除之前设置的定时器。* 在延迟时间内连续调用函数时,会不断清除之前的定时器并重新设置新的定时器,确保只有在最后一次调用后的延迟时间结束后才会执行函数。* 通过闭包保存定时器变量,确保每次调用都使用同一个定时器。* 优点是简单易懂,缺点是无法立即触发函数,只有在延迟时间结束后才会执行函数。*/// 用来测试的方法
function test() {console.log('测试防抖');
}
// 获取到页面的 dom 节点
let de = document.querySelector('.testDebounce');
// 使用第一种方法实现防抖
de.addEventListener('click', debounce(test, 2000))
// 第二种写法:包含是否立即执行
// 在执行事件之后,会立即执行一次,剩下的时候,就是会在定时器结束才会继续执行
/*** * @param {*} func 需要执行的函数 * @param {*} delay 延迟执行的时间* @param {*} triggleNow 是否立即执行 --> 布尔值* @returns */
function debounce(func, delay, triggleNow) {var timer = nullvar debounced = function() {var self = thisvar argu = argumentsif (timer) {clearTimeout(timer)}if (triggleNow) {var noTimer = !timertimer = setTimeout(function() {timer = null}, delay)if (noTimer) {func.apply(self, argu)}} else {timer = setTimeout(function() {func.apply(self, argu)}, delay)}}debounced.remove = function() {clearTimeout(timer)timer = null}return debounced
}
/*** 使用计时器和闭包实现防抖。* 在函数被调用时,清除之前设置的定时器。* 如果设置了 triggleNow 参数为 true,则在函数第一次被调用时立即执行函数,之后的连续调用会在延迟时间结束后才能再次触发函数。* 如果没有设置 triggleNow 或设置为 false,则在延迟时间结束后执行函数。* 通过闭包保存定时器变量和函数执行状态,确保只有符合条件的调用才能触发函数。* 通过 debounced.remove 方法可以手动移除定时器,取消防抖效果。* 优点是灵活性高,可以设置立即触发和手动移除定时器,缺点是稍显复杂。*/// 用来测试的方法
function test() {console.log('测试防抖');
}
// 获取到页面的 dom 节点
let de = document.querySelector('.testDebounce');
// 使用第二种方法实现防抖
de.addEventListener('click', debounce(test, 2000, true))
三、节流
节流是什么:
1、事件被触发,n 秒之内只执行一次事件处理函数
2、无论在这段时间内触发了多少次函数调用,只会执行一次
节流的场景:
1、输入验证(验证长度等)
2、ajax 提交
具体实现:
// 第一种写法:
// 通过一个变量来判断当前函数的执行状态,形成闭包
/*** * @param {*} func 需要执行的函数* @param {*} delay 延迟执行的时间* @returns */
function throttle1(func, delay) {let timer = nulllet shouldExecute = truereturn function(...args) {if (!shouldExecute) {return}shouldExecute = falsetimer = setTimeout(function() {func.apply(this, args)shouldExecute = true}, delay)}
}
/*** 具体实现流程:* 使用 setTimeout 实现节流。* 在函数被调用时,设置一个延迟定时器,并在延迟时间结束后执行函数。* 通过一个标志位 shouldExecute 控制是否执行函数,在延迟时间内连续调用函数只会执行一次。* 一旦函数执行完毕,将 shouldExecute 设置为 true,表示可以再次执行函数。* 优点是延迟时间可以精确控制,缺点是在延迟时间内的连续函数调用会被忽略。*/// 用来测试的方法
function test() {console.log('节流数据');
}
// 获取到页面的 dom 节点
let tt = document.querySelector('.testThrottle')// 使用第一种方法实现节流
tt.addEventListener('click', throttle1(test, 2000))
// 第二种写法:
// 通过两个时间戳来判断当前函数的执行状态,也会形成闭包
/*** * @param {*} func 需要执行的函数* @param {*} delay 延迟执行的时间* @returns */
function throttle2(func, delay) {let timer = nulllet begin = new Date().getTime()return function() {let self = thislet argu = argumentslet current = new Date().getTime()clearTimeout(timer)if (current - begin >= delay) {func.apply(self, argu)begin = current} else {timer = setTimeout(function() {func.apply(self, argu)}, delay)}}
}
/*** 具体实现流程:* 使用计时器和时间戳实现节流。* 在函数被调用时,记录当前时间戳 current。* 如果当前时间戳距离上一次调用时间戳 begin 大于等于设定的延迟时间 delay,则立即执行函数,并更新 begin 的值为当前时间戳。* 如果当前时间戳距离上一次调用时间戳 begin 小于延迟时间 delay,则设置一个延迟定时器,在延迟时间结束后执行函数。* 优点是在延迟时间内的连续函数调用不会被忽略,缺点是延迟时间不是精确的,而是最小延迟时间和连续函数调用之间的时间差*/// 用来测试的方法
function test() {console.log('节流数据');
}
// 获取到页面的 dom 节点
let tt = document.querySelector('.testThrottle')// 使用第二种方法实现节流
tt.addEventListener('click', throttle2(test, 2000))
总结:
防抖和节流都能够优化函数执行频率,提升性能,控制事件触发频率,优化用户输入,实现平滑动画等。在需要控制函数执行频率以避免资源浪费、提高交互体验或优化动画效果的场景中,防抖和节流都是非常有用的技术手段
如果还是不太能理解他俩的区别,之前我在一个评论区看到一个神评:“防抖就是回城,节流就是放技能”,相信看到这句话,就能通俗易懂的理解他俩之间的区别了。
相关文章:
前端性能优化:防抖与节流
一、防抖和节流主要是干什么的 防抖和节流主要用于控制函数执行的频率,通过限制函数的触发次数,避免函数被过度调用而引发的性能问题或产生不必要的副作用。 二、防抖 防抖是什么: 1、对于在事件被触发 n 秒后再执行的回调 --> 延迟执行 2、如果…...

Copilot 编程助手的介绍及使用
介绍 Copilot 是2021年由 GitHub 与 OpenAI 合作研发的一款编程助手,同时也是全球首款使用OpenAI Codex模型(GPT-3后代)打造的大规模生成式AI开发工具。 Copilot 底层模型目前经过了数十亿行公开代码的训练,与大多数代码辅助工具…...

数据库专题(oracle基础和进阶)
前言 本专题主要记录自己最近学的数据库,有兴趣一起补习的可以一起看看,有补充和不足之处请多多指出。希望专题可以给自己还有读者带去一点点提高。 数据库基本概念 本模块有参考:数据库基本概念-CSDN博客 数据库管理系统是一个由互相关联的…...
web蓝桥杯2022省赛真题:水果拼盘
代码及注释: /* TODO:待补充代码 */ #pond {display: flex; //flex布局flex-direction: column; //主轴方向从上到下flex-wrap: wrap; //子元素换行 } 知识点: flex弹性布局 父元素:diasplay: flex; flex-d…...

Web核心
目录 Web核心HTTP概念:协议特点:请求数据格式响应数据格式 Tomcat简介基本使用配置部署项目IDEA中创建 Maven Web 项目 IDEA使用Tomcat Servlet简介快速入门执行流程生命周期体系结构Servlet urlPattern配置一个Servlet,可以配置多个 urlPatt…...

iOS应用审核问题解决方案及优化方法 ✨
摘要 本文将针对iOS应用提交审核时可能遇到的问题,如“你必须在Xcode中添加com.apple.developer.game-center密钥”,以及突然间提交送审报错情况进行探讨。通过大量查询资料和尝试,结合案例分析,提供了解决方案和优化方法…...
java post、get请求第三方https接口
java post、get请求第三方https接口 前段时间做项目新加功能由于要对接其它系统,请求系统接口传输数据。写完后发现我写的这个方法和网上现有的例子有点不太一样,可能是因为我做的项目是政务网的原因,但我想正常的即便是互联网的系统请求方式…...
【C语言】鸡兔同笼,鸡和兔共 100 只,共 284 只脚,求鸡和兔的个数。
鸡兔同笼,鸡和兔共 100 只,共 284 只脚,求鸡和兔的个数。 int main() {for (int i 0; ; i){if (2 * i 4 * (100 - i) 284){printf("鸡的数量:%d,兔子的数量:%d", i, 100 - i);break;} } }这里直接算出题…...

沪漂8年回郑州三年如何走上创业之路
大家好,我是大牛,目前人在郑州。 现在标签是: 创业者🚗🐸 (注册有自己的公司,主要是为了自己的产品和接外包项目)独立开发者👨🏻💻 (有自己的小项目)数字游民&…...

MySQL数据库—事务与存储类型
一、事务: 1.事务的概念: 事务是一种机制、一个操作序列,包含了一组数据库操作命令,并且把所有的命令作为一个整体一起向系统提交或撤销操作请求,即这组数据库命令要么都执行,要么都不执行。事务是一个不…...

蓝桥杯刷题8
1. 世纪末的星期 import java.util.Calendar; public class Main {public static void main(String[] args) {Calendar calendar Calendar.getInstance();for(int year 1999;year<100000;year100){calendar.set(Calendar.YEAR,year);calendar.set(Calendar.MONTH,11);cale…...
Java中的String字符串练习
目录 Java中的String字符串练习 01-用户登录 02-遍历字符串并统计字符个数 03-字符串拼接 04-字符串反转 注意点 05-金额转化(简单) 代码解释: 06-手机号屏蔽 07-身份证号码查看 易错点: 08-敏感词替换 01-用户登录 package com.xiaonan.exercise06;import java.u…...

基于JavaWeb SSM mybatis 学生信息管理系统设计和实现以及文档报告
基于JavaWeb SSM mybatis 学生信息管理系统设计和实现以及文档报告 博主介绍:多年java开发经验,专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》 欢迎点赞 收藏 …...
二进制源码部署mysql8.0.35
二进制部署mysql8.0.35 创建mysql用户 [rootzyq ~]#: useradd -r -s /sbin/nologin -M mysql [rootzyq ~]#: id mysql uid990(mysql) gid990(mysql) groups990(mysql)上传mysql文件 [rootzyq ~]#: ls anaconda-ks.cfg mysql-8.0.35-linux-glibc2.28-x86_64.tar.xz解压 [roo…...

PHP 读取嵌入式数据 SQLite3
SQLite3 属于轻量级开源的嵌入式关系型数据库,但它支持 ACID(Atomicity,Consistency,Isolation,Durability) 事务。 SQLite Download Page: https://www.sqlite.org/download.html 第一步:在 php.ini 中开启 extensionsqlite3 第二步:连接数…...

【代驾+顺风车+货运】全开源双端APP代驾+顺风车+货运代驾小程序源码
内容目录 一、详细介绍二、效果展示1.部分代码2.效果图展示 一、详细介绍 系统是基于Thinkphpuniapp开发的,全开源未加密,这套源码可以拿回去自己做二开 后台用户端司机端 功能详情介绍: 车主实名认证,驾驶证认证,车…...
C++语言学习(三)—— 文件操作
目录 一、文件操作 1.1 打开文件 1.2 关闭文件 1.3 读取文件 1.4 写入文件 1.5 文件指针 1.6 文件状态 1.7 其他文件操作 二、文件操作函数 2.1 打开文件函数 2.2 关闭文件函数 2.3 写入文件函数 2.4 读取文件函数 2.5 读取一行函数 2.6 获取文件大小函数 2.7 …...

linux文本三剑客 --- grep、sed、awk
1、grep grep:使用正则表达式搜索文本,将匹配的行打印出来(匹配到的标红) 命令格式:grep [option] pattern file <1> 命令参数 -A<显示行数>:除了显示符合范本样式的那一列之外,并…...

leetcode 107.二叉树的层序遍历II
题目 思路 正常层序遍历输出: [[3],[9,20],[15,7]] 这道题要求的输出:[[15,7],[9,20],[3]] 可以观察到,只要我们把原来的结果reverse一下就行了。 代码 //leetcode submit region begin(Prohibit modification and deletion)import java…...
Java生成唯一ID的方式有哪些?
在Java中生成唯一ID的方法多种多样,以下是几种常用方法及其示例代码: 1. 使用UUID UUID是一种普遍采用的生成唯一ID的方法,Java通过java.util.UUID类提供了简单的方法来生成。 import java.util.UUID;public class UniqueIdExample {publi…...
基于大模型的 UI 自动化系统
基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...
CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型
CVPR 2025 | MIMO:支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题:MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者:Yanyuan Chen, Dexuan Xu, Yu Hu…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...

基于Flask实现的医疗保险欺诈识别监测模型
基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施,由雇主和个人按一定比例缴纳保险费,建立社会医疗保险基金,支付雇员医疗费用的一种医疗保险制度, 它是促进社会文明和进步的…...
反射获取方法和属性
Java反射获取方法 在Java中,反射(Reflection)是一种强大的机制,允许程序在运行时访问和操作类的内部属性和方法。通过反射,可以动态地创建对象、调用方法、改变属性值,这在很多Java框架中如Spring和Hiberna…...
C++.OpenGL (10/64)基础光照(Basic Lighting)
基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用
1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...

Java面试专项一-准备篇
一、企业简历筛选规则 一般企业的简历筛选流程:首先由HR先筛选一部分简历后,在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如:Boss直聘(招聘方平台) 直接按照条件进行筛选 例如:…...
「全栈技术解析」推客小程序系统开发:从架构设计到裂变增长的完整解决方案
在移动互联网营销竞争白热化的当下,推客小程序系统凭借其裂变传播、精准营销等特性,成为企业抢占市场的利器。本文将深度解析推客小程序系统开发的核心技术与实现路径,助力开发者打造具有市场竞争力的营销工具。 一、系统核心功能架构&…...

论文阅读:LLM4Drive: A Survey of Large Language Models for Autonomous Driving
地址:LLM4Drive: A Survey of Large Language Models for Autonomous Driving 摘要翻译 自动驾驶技术作为推动交通和城市出行变革的催化剂,正从基于规则的系统向数据驱动策略转变。传统的模块化系统受限于级联模块间的累积误差和缺乏灵活性的预设规则。…...