网站首页 > 技术文章 正文
作者:前端点线面来源:前端点线面
性能一直是前端老生常谈的一个话题,其中有一个性能问题就是我们会频繁的触发一些事件,例如mousemove、scroll、resize等,虽然浏览器已经对这些事件的触发做了一些优化,但是如果在很短的时间内频繁的触发仍然会影响性能,这个时候就需要今天的主角:防抖和节流,利用它们来进行优化,提高性能。
1 防抖
1.1 定义
防抖就是将多次高频操作优化为只在最后一次执行(某个函数在某段时间内,无论触发了多少次回调,都只执行最后一次)。通常的使用场景是:用户输入,只需在输入完成后做一次输入校验即可。
1.2 实现
防抖是将多次操作合并为一次操作完成,其原理就是维护一个计时器,在规定的时间后触发函数,但是在该规定时间内再次触发的话就会取消之前的定时器而重新设置,从而保证了只有最后一次操作能够被触发。其实现步骤如下所示:
- 利用闭包保存一个timer变量,然后返回一个函数(这个返回的函数就是后续频繁触发操作中调用的函数);
- 根据标志位判断是否第一次需要立即执行(因为有些情况是需要首次调用函数立即执行的,若没有该参数,就会在定时器到了之后才会执行);
- 当有新的触发时,若存在定时器,则清空该定时器;
- 设定一个新的定时器,重新计时。
function debounce(fn, wait, immediate) {
let timer = null;
return function (...args) {
// 立即执行的功能(timer为空表示首次触发)
if (immediate && !timer) {
fn.apply(this, args);
}
// 有新的触发,则把定时器清空
timer && clearTimeout(timer);
// 重新计时
timer = setTimeout(() => {
fn.apply(this, args);
}, wait);
}
}
1.3 效果预览
观察效果图可以验证上述的理论知识:
- 防抖之后输出内容的频次降低了;
- 防抖之后,其在超过一定时间之后才会输出内容。
2 节流
2.1 定义
节流就是每隔一段时间后执行一次,也就是降低频率,将高频操作优化成低频操作。通常使用场景:滚动条事件、resize事件、动画等,通常每隔100-500ms执行一次即可。
2.2 实现
节流函数的实现方式有两种:定时器版本、时间戳版本,这两者各有千秋,下面来简要实现一下。
2.2.1 定时器版本
定时器版本的节流函数其重点是利用闭包保存timer变量,具有两个特点:
- n秒后才会执行第一次(定时器到了时间后才会触发);
- 停止触发后节流函数还会执行一次(因为该函数是延迟执行的,当停止触发时其任务已经到了队列中,所以停止后还会执行一次)。
// 定时器版本
function throttle(fn, wait) {
let timer = null;
return function(...args) {
if (!timer) {
timer = setTimeout(() => {
fn.apply(this, args);
timer = null;
}, wait)
}
}
}
2.2.2 时间戳版本
时间戳版本的节流函数重点是利用闭包保存上一次的时间previous,具有两个特点:
开始触发后会立即执行(因为previous开始会被赋值为0);
停止触发后不再执行(因为该函数是同步任务,在触发的时候就会进行相应的判断,所以就不存在停止触发后再执行的情况)。
// 时间戳版本
function throttle(fn, wait) {
// 上一次执行时间
let previous = 0;
return function(...args) {
// 当前时间
let now = +new Date();
if (now - previous > wait) {
previous = now;
fn.apply(this, args);
}
}
}
2.3 效果预览
观察效果图可以验证上述的理论知识:
- 节流确实降低了内容的输出频率,将高频变为低频;
- 时间戳版本的节流函数在首次会输出内容,但是最后一次的内容不会输出(谨慎使用);
- 定时器版本的节流函数确实不会立刻打印内容,而是超过一定时间之后才会打印;此外,其最后输入的内容会被打印出来。
- 上一篇: 前端面试:什么是节流,在什么场景中使用
- 下一篇: 函数节流的6种应用场景,与防抖函数有什么区别?
猜你喜欢
- 2025-09-11 Vue 自定义指令_vue 自定义指令实现v-bind
- 2025-09-11 为什么说 ReadableStream 是现代 Web 架构的关键拼图?
- 2025-09-11 2025前端面试题-React基础篇_前端react必读书籍推荐
- 2025-09-11 肉鸭产业养殖端是否需要升级?我们该怎么做?
- 2025-09-11 为什么你的前端首屏慢?从 TTFB 到 CLS 的系统性优化清单
- 2024-12-08 函数节流的6种应用场景,与防抖函数有什么区别?
- 2024-12-08 前端面试:什么是节流,在什么场景中使用
- 2024-12-08 前端都应该要掌握的防抖和节流
- 2024-12-08 秒懂前端防抖和节流(无需代码)
你 发表评论:
欢迎- 最近发表
-
- 用AI做微信小程序的完整步骤_如何用ai制作微信表情包
- 自习室预约的微信小程序设计与实现-计算机毕业设计源码+LW文档
- 微信小程序开发入门指南_微信小程序开发入门教程
- 写字机器人好用吗? 组装就花了5个小时 还要学习软件、录入字体
- 白描网页版 - 高效准确且免费的OCR文字识别工具
- 字体图形面板与图标字体使用_字体图标的优势和劣势
- 作为前端工程师必须懂得的33个CSS核心概念
- Flutter程序员开发炫酷的登录页面 字体库运用 路由学习 源码分享
- 2025Q3开源字体盘点:让你的代码和文档'颜值'飙升!
- Agent杂谈:Agent的能力上下限及「Agent构建」核心技术栈调研分享~
- 标签列表
-
- 前端设计模式 (75)
- 前端性能优化 (51)
- 前端模板 (66)
- 前端跨域 (52)
- 前端缓存 (63)
- 前端aes加密 (58)
- 前端脚手架 (56)
- 前端md5加密 (54)
- 前端路由 (61)
- 前端数组 (73)
- 前端js面试题 (50)
- 前端定时器 (59)
- Oracle RAC (76)
- oracle恢复 (77)
- oracle 删除表 (52)
- oracle 用户名 (80)
- oracle 工具 (55)
- oracle 内存 (55)
- oracle 导出表 (62)
- oracle约束 (54)
- oracle 中文 (51)
- oracle链接 (54)
- oracle的函数 (58)
- oracle面试 (55)
- 前端调试 (52)
本文暂时没有评论,来添加一个吧(●'◡'●)