防抖与节流

防抖与节流:Vue3+TS 实战指南

作为一个常被产品经理吐槽"页面卡成PPT"的程序员,今天带你彻底掌握两个让页面飞起来的神器:节流(Throttle)防抖(Debounce) 。本文使用 Vue3 + TypeScript + Vite + VueUse 实战演示,无需造轮子,直接上手!


一、为什么页面会卡顿?

先看两个典型场景:

  1. 搜索框场景

    用户每输入一个字母就发起请求,输入"前端开发"(4字)触发 8 次请求 → 服务器压力巨大

  2. 滚动加载场景

    用户滚动鼠标时,代码疯狂计算,页面卡顿如PPT

解决方案:节流和防抖就像"交通管理员",精准控制请求频率,让页面丝滑如丝绸。


二、核心区别

🧠 核心区别:执行时机不同

特性 防抖 (Debounce) 节流 (Throttle)
执行时机 最后一次触发后等待一段时间才执行 每隔一段时间执行一次
执行次数 无论触发多少次,最终只执行1次 每个时间间隔内最多执行1次
触发逻辑 "等你停手了,我再行动" "按固定频率执行,拒绝插队"
典型比喻 电梯关门:最后一个人进来后3秒关门 地铁发车:每5分钟一班,必须等5分钟

💡 关键理解

防抖关注"最终结果",节流关注"执行频率"

(搜索要结果,滚动要过程)


三、场景选择

场景 推荐方式 为什么? 实际案例
搜索框输入 ✅ 防抖 用户输入结束再请求,避免无效请求 电商网站搜索框
**页面滚动 ** ✅ 节流 需持续响应滚动动作 无限滚动加载
按钮点击 ✅ 节流 防止用户快速连续点击 提交按钮、点赞按钮
表单实时验证 ✅ 防抖 输入结束再验证,避免干扰用户 用户名/邮箱格式校验
实时输入监听 ✅ 防抖 需要实时响应输入变化 密码强度提示

💡 一句话总结

要结果用防抖,要过程用节流

(搜索要结果,滚动要过程)


四、实战

✅ 无需手写,对于Vue3工程,可以直接使用 VueUse 组件

bash 复制代码
npm install @vueuse/core

1. 防抖(Debounce)

1. 使用示例
vue 复制代码
<template>
  <div>
    <el-input
      v-model="keyword"
      @blur="debouncedSearch"
      placeholder="搜索点什么..."
      style="width: 300px"
    />
    <p>搜索关键词:{{ keyword }}</p>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { useDebounceFn } from '@vueuse/core'

const keyword = ref('')

const searchAPI = () => console.log('发起搜索请求时间:', new Date().toLocaleString())

const debounce = useDebounceFn(() => searchAPI(), 1000)
const debouncedSearch = () => {
  debounce()
  console.log('失去焦点的时间:', new Date().toLocaleString())
}
</script>
2. useDebounceFn函数用法
参数名 类型 默认值 说明
fn (...args: any[]) => any 必填 需要防抖的原始函数
ms number 0 防抖延迟(毫秒),停手多少 ms 后才执行 fn
options DebounceFilterOptions 见下方 高级行为配置对象(可选)
DebounceFilterOptions 子项
选项名 类型 默认值 说明
maxWait number undefined 最大等待时间,超时必执行
rejectOnCancel boolean false 手动 cancel() 后,promise() 是否 reject 而不是一直 pending
返回值附加方法
方法名 含义
debounced(...args) 正常触发,防抖生效
debounced.cancel() 取消当前计时,不会执行原函数
debounced.flush() 立即执行原函数并清空计时
debounced.promise(...args) 返回 Promise,resolve 原函数返回值

2. 节流(Throttle)

1. 使用示例
vue 复制代码
<template>
  <div>
    <el-button type="primary" @click="throttleSearch">点击</el-button>
  </div>
</template>

<script setup lang="ts">
import { useThrottleFn } from '@vueuse/core'
const searchAPI = () => console.log('发起搜索请求时间:', new Date().toLocaleString())

const throttle = useThrottleFn(() => searchAPI(), 1000)

let count = 0
const throttleSearch = () => {
  throttle()
  console.log(`点击了${++count}次`)
}
</script>
2. useThrottleFn函数用法
参数名 类型 默认值 说明
fn (...args: any[]) => any 必填 需要被节流包装的原始函数
ms number 0 节流间隔(毫秒),在该时间段内最多执行一次 fn
options ThrottleFnOptions 见下方 高级行为配置对象(可选)
ThrottleFnOptions 子项
选项名 类型 默认值 说明
leading boolean true 是否在节流周期开始立即执行一次原函数
trailing boolean false 是否在节流周期结束再执行一次原函数
rejectOnCancel boolean false 手动 cancel() 后,promise() 是否 reject
返回值函数
方法名 含义
throttled(...args) 正常触发,节流生效
throttled.cancel() 取消当前计时,不会执行原函数
throttled.flush() 立即执行原函数并清空计时
throttled.promise(...args) 返回 Promise,resolve 原函数返回值

五、口诀

技术 核心思想 适用场景 一句话总结
防抖 等你停手了,我再行动 搜索、表单验证 要结果,别急着动
节流 按固定频率执行 滚动、拖拽 要过程,别太急

总结

节流和防抖是前端性能的"刹车系统"

✅ 用对 = 页面丝滑如丝绸

❌ 用错 = 服务器崩溃+产品经理暴怒

建议收藏本文,下次产品说"页面卡"时,先检查是否忘了加防抖/节流! 😄

| 节流 | 按固定频率执行 | 滚动、拖拽 | 要过程,别太急 |


总结

节流和防抖是前端性能的"刹车系统"

✅ 用对 = 页面丝滑如丝绸

❌ 用错 = 服务器崩溃+产品经理暴怒

建议收藏本文,下次产品说"页面卡"时,先检查是否忘了加防抖/节流! 😄

相关推荐
m0_7190841127 分钟前
React笔记张天禹
前端·笔记·react.js
Ziky学习记录41 分钟前
从零到实战:React Router 学习与总结
前端·学习·react.js
wuhen_n1 小时前
JavaScript链表与双向链表实现:理解数组与链表的差异
前端·javascript
wuhen_n1 小时前
JavaScript数据结构深度解析:栈、队列与树的实现与应用
前端·javascript
狗哥哥1 小时前
微前端路由设计方案 & 子应用管理保活
前端·架构
前端大卫2 小时前
Vue3 + Element-Plus 自定义虚拟表格滚动实现方案【附源码】
前端
却尘2 小时前
Next.js 请求最佳实践 - vercel 2026一月发布指南
前端·react.js·next.js
ccnocare2 小时前
浅浅看一下设计模式
前端
Lee川2 小时前
🎬 从标签到屏幕:揭秘现代网页构建与适配之道
前端·面试
Ticnix3 小时前
ECharts初始化、销毁、resize 适配组件封装(含完整封装代码)
前端·echarts