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

前端性能优化:防抖与节流

一、防抖和节流主要是干什么的

防抖和节流主要用于控制函数执行的频率,通过限制函数的触发次数,避免函数被过度调用而引发的性能问题或产生不必要的副作用。

二、防抖

防抖是什么:

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密钥”,以及突然间提交送审报错情况进行探讨。通过大量查询资料和尝试,结合案例分析,提供了解决方案和优化方法&#xf…...

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 学生信息管理系统设计和实现以及文档报告 博主介绍&#xff1a;多年java开发经验&#xff0c;专注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 属于轻量级开源的嵌入式关系型数据库&#xff0c;但它支持 ACID(Atomicity,Consistency,Isolation,Durability) 事务。 SQLite Download Page: https://www.sqlite.org/download.html 第一步&#xff1a;在 php.ini 中开启 extensionsqlite3 第二步&#xff1a;连接数…...

【代驾+顺风车+货运】全开源双端APP代驾+顺风车+货运代驾小程序源码

内容目录 一、详细介绍二、效果展示1.部分代码2.效果图展示 一、详细介绍 系统是基于Thinkphpuniapp开发的&#xff0c;全开源未加密&#xff0c;这套源码可以拿回去自己做二开 后台用户端司机端 功能详情介绍&#xff1a; 车主实名认证&#xff0c;驾驶证认证&#xff0c;车…...

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&#xff1a;使用正则表达式搜索文本&#xff0c;将匹配的行打印出来&#xff08;匹配到的标红&#xff09; 命令格式&#xff1a;grep [option] pattern file <1> 命令参数 -A<显示行数>&#xff1a;除了显示符合范本样式的那一列之外&#xff0c;并…...

leetcode 107.二叉树的层序遍历II

题目 思路 正常层序遍历输出&#xff1a; [[3],[9,20],[15,7]] 这道题要求的输出&#xff1a;[[15,7],[9,20],[3]] 可以观察到&#xff0c;只要我们把原来的结果reverse一下就行了。 代码 //leetcode submit region begin(Prohibit modification and deletion)import java…...

Java生成唯一ID的方式有哪些?

在Java中生成唯一ID的方法多种多样&#xff0c;以下是几种常用方法及其示例代码&#xff1a; 1. 使用UUID UUID是一种普遍采用的生成唯一ID的方法&#xff0c;Java通过java.util.UUID类提供了简单的方法来生成。 import java.util.UUID;public class UniqueIdExample {publi…...

代码随想录day44:动态规划over,回文子串及字序列

文章目录 day44&#xff1a;动态规划over&#xff0c;回文子串647.回文子串516.最长回文子序列 day44&#xff1a;动态规划over&#xff0c;回文子串 647.回文子串 class Solution {public int countSubstrings(String s) { // 布尔类型的dp[i][j]&#xff1a;表示区间范围[i…...

ElasticSearch启动报错:Exception in thread “main“ SettingsException

Exception in thread "main" SettingsException[Failed to load settings from [elasticsearch.yml]]; nested: ParsingException[Failed to parse object: expecting token of type [START_OBJECT] but found [VALUE_STRING]]; 这个报错说明elasticsearch.yml这个配…...

git配置密钥

要配置 Git 密钥&#xff0c;可以按照以下步骤进行操作&#xff1a; 1.生成密钥&#xff1a;首先&#xff0c;在终端或命令提示符中运行以下命令生成密钥对&#xff1a; ssh-keygen -t rsa -b 4096 -C "dengweng-pulse.net"这将生成一个 RSA 密钥对&#xff0c;其中…...

Pandas库常用方法、函数集合

Pandas是Python数据分析处理的核心第三方库&#xff0c;它使用二维数组形式&#xff0c;类似Excel表格&#xff0c;并封装了很多实用的函数方法&#xff0c;让你可以轻松地对数据集进行各种操作。 这里列举下Pandas中常用的函数和方法&#xff0c;方便大家查询使用。 读取 写…...

Qt实现TFTP Server和 TFTP Client(一)

1 概述 TFTP协议是基于UDP的简单文件传输协议&#xff0c;协议双方为Client和Server.Client和Server之间通过5种消息来传输文件,消息前两个字节Code是消息类型&#xff0c;消息内容随消息类型不同而不同。传输模式有三种&#xff1a;octet,netascii和mail&#xff0c;octet为二…...

MySQL数据库的日志管理以及备份和恢复

目录 1、日志管理 2、查询日志 3、数据备份的重要性 4、数据库备份的分类 4.1物理备份 4.2逻辑备份&#xff1a; 4.3完全备份 5、常见的备份方法 6、MySQL完全备份 6.1MySQL完全备份优缺点 6.2数据库完全备份分类 6.2.1物理冷备份与恢复 6.2.2mysqldump备份…...

Maven发布开源框架到远程仓库

1.背景 当你写了一个自我感觉良好的开源工具希望给他人分享&#xff0c;如果只是在github等网站进行公布之外&#xff0c;用户使用起来还不是很方便&#xff0c;特别是当你提供是特定领域的基础工具。你还可以把它部署到中央仓库&#xff0c;这样别人使用就会方便很多。接下来…...

Qt创建窗口选择的三个父类介绍 ----- QWidget、QMainWindow、QDialog

QWidget类 简介 QWidget是Qt中所有用户界面元素的基类。它提供了窗口的基本功能&#xff0c;并允许用户自定义窗口的外观和行为。QWidget可以包含其他QWidget子类的子窗口&#xff0c;从而实现复杂的用户界面。 特性 提供了窗口的基本功能&#xff0c;包括绘制、事件处理、…...

论文翻译 - Defending Against Alignment-Breaking Attacks via Robustly Aligned LLM

论文链接&#xff1a;https://arxiv.org/pdf/2309.14348.pdf Defending Against Alignment-Breaking Attacks via Robustly Aligned LLM Abstract1 Introduction2 Related Works3 Our Proposed Method3.1 Threat Model3.2 Our Proposed Method3.3 Practical Designs3.4 Theoret…...

Kafka总结问题

Kafka Kafka Kafka Kafka的核心概念/ 结构 topoic Topic 被称为主题&#xff0c;在 kafka 中&#xff0c;使用一个类别属性来划分消息的所属类&#xff0c;划分消息的这个类称为 topic。topic 相当于消息的分配标签&#xff0c;是一个逻辑概念。主题好比是数据库的表&#xff0…...