当前位置:首页 > 技术分析 > 正文内容

频繁触发事件崩溃?JS 防抖节流 3 板斧,第 3 种 90% 人没用过!

ruisui881个月前 (05-08)技术分析23

在前端开发的日常里,像监听窗口 resize、输入框实时搜索、按钮高频点击这类场景,简直不要太常见。可一旦处理不好,频繁触发的事件分分钟让页面卡顿、浏览器假死,甚至把服务器请求搞到崩溃,用户体验直接 “原地爆炸”!别急,JS 里的防抖和节流技术就是解决这些难题的 “秘密武器”,今天就带大家解锁 3 种超实用方案。

技术原理剖析

防抖(Debounce):就像等电梯关门,你一直按关门按钮,电梯不会立刻关门,而是等你一段时间不按了,才执行关门动作。在代码里,防抖就是当事件被频繁触发时,设定一个延迟时间,只有在延迟时间内事件不再触发,才执行对应函数。

节流(Throttle):好比过独木桥,一次只允许一个人通过,规定好间隔时间。在代码中,节流是指在一定时间间隔内,无论事件触发多少次,都只执行一次函数,以此控制函数执行频率。

代码示例详解

方案一:普通防抖函数

// 创建一个防抖函数,接收要执行的函数和延迟时间
function debounce(func, delay) {
let timer;
return function() {
// 每次触发事件时,清除之前的定时器
if (timer) {
clearTimeout(timer);
}
// 设置新的定时器,延迟delay毫秒后执行func函数
timer = setTimeout(() => {
func.apply(this, arguments);
}, delay);
};
}
// 使用示例:监听窗口resize事件
window.addEventListener('resize', debounce(() => {
console.log('窗口大小改变,执行相关操作');
}, 300));

方案二:普通节流函数

// 创建一个节流函数,接收要执行的函数和时间间隔
function throttle(func, limit) {
let inThrottle;
return function() {
// 如果当前处于节流状态(inThrottle为true),则直接返回,不执行函数
if (inThrottle) return;
// 执行函数
func.apply(this, arguments);
// 设置为节流状态
inThrottle = true;
// 延迟limit毫秒后,将inThrottle设置为false,允许下次函数执行
setTimeout(() => {
inThrottle = false;
}, limit);
};
}
// 使用示例:监听滚动事件
window.addEventListener('scroll', throttle(() => {
console.log('页面滚动,执行相关操作');
}, 200));

方案三:lodash 库的防抖节流

// 引入lodash库
const _ = require('lodash');
// 使用lodash的防抖函数,延迟300毫秒
const debouncedFunc = _.debounce(() => {
console.log('lodash防抖函数执行');
}, 300);
// 使用lodash的节流函数,间隔200毫秒
const throttledFunc = _.throttle(() => {
console.log('lodash节流函数执行');
}, 200);

对比效果实测

在模拟高频触发场景下,未处理的事件触发 100 次时,页面卡顿明显;使用普通防抖函数,在延迟 300ms 后,事件触发次数减少到 1 - 2 次;普通节流函数将事件触发频率限制在每 200ms 一次;lodash 库的防抖节流不仅代码简洁,性能表现也十分稳定,在复杂项目中优势更明显。

扩展思考

防抖和节流在实际项目中的应用远不止这些,比如在移动端的 touchmove 事件处理、游戏开发的动画渲染频率控制中都大有用处。而且在 React、Vue 等框架里,使用防抖节流又有哪些最佳实践?当项目对性能要求极高时,是选择手写还是使用第三方库更合适?

是手写防抖节流更能掌控细节,还是直接用 lodash 这类库更香?大伙在项目里都咋用的?快来评论区分享你的实战经验,咱们好好唠唠!

扫描二维码推送至手机访问。

版权声明:本文由ruisui88发布,如需转载请注明出处。

本文链接:http://www.ruisui88.com/post/3871.html

标签: js 防抖函数
分享给朋友:

“频繁触发事件崩溃?JS 防抖节流 3 板斧,第 3 种 90% 人没用过!” 的相关文章

vue组件间的九种通信方式

前言Vue组件实例间的作用域是相互独立的,而通常一个页面是由很多个组件构成,这些组件可能又嵌套了组件,形成了一个关系网图,它们的关系可能是像下图中一样,大致分为两种使用场景,父子组件间通信和非父子组件间通信,父子组件间通信又分为直接父子关系和间接父子关系。vue提供了多种通信方法,针对不同的通信需求...

GitLab-合并请求

描述合并请求可用于在您对项目进行的其他人员之间交换代码,并轻松与他们讨论更改。合并请求的步骤步骤1-在创建新的合并请求之前,GitLab中应该有一个创建的分支。您可以参考本章来创建分支-步骤2-登录到您的GitLab帐户,然后转到“ 项目”部分下的项目 -步骤3-单击“ 合并请求”选项卡,然后单击“...

html5+css3做的响应式企业网站前端源码

大家好,今天给大家介绍一款,html5+css3做的响应式企业网站前端源码 (图1)。送给大家哦,获取方式在本文末尾。首页banner幻灯片切换特效(图2)首页布局简约合理(图3)关于我们页面(图4)商品列表(图5)商品详情(图6)服务介绍(图7)新闻列表(图8)联系我们(图9)源码完整,需要的朋友...

一文让你彻底搞懂 vue-Router

路由是网络工程里面的专业术语,就是通过互联把信息从源地址传输到目的地址的活动。本质上就是一种对应关系。分为前端路由和后端路由。后端路由:URL 的请求地址与服务器上的资源对应,根据不同的请求地址返回不同的资源。前端路由:在单页面应用中,根据用户触发的事件,改变URL在不刷新页面的前提下,改变显示内容...

Vue学习笔记之动态路由的参数传递应用及技巧

路由的参数传递:①通过params的类型· 配置路由格式:/router/:id· 传递的方式:在path后面跟上对应的值· 传递后形成的路径:/router/list,/router/profile这个就是前两篇中提到的"动态路由"中有应用过这个方法:②通过query的类型(对象方...

Vue实现动态路由

通常我们在vue项目中都是前端配置好路由的,但在一些项目中我们可能会遇到权限控制,这样我们就涉及到动态路由的设置了。动态路由设置一般有两种:(1)、简单的角色路由设置: 比如只涉及到管理员和普通用户的权限。通常直接在前端进行简单的角色权限设置(2)、复杂的路由权限设置: 比如OA系统、多种角色的权限...