防抖与节流

防抖与节流: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 原函数返回值

五、口诀

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

总结

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

✅ 用对 = 页面丝滑如丝绸

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

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

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


总结

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

✅ 用对 = 页面丝滑如丝绸

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

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

相关推荐
叁两16 分钟前
用opencode打造全自动公众号写作流水线,AI 代笔太香了!
前端·人工智能·agent
golang学习记21 分钟前
GitLens 十大神技:彻底改变你在 VS Code 中的 Git 工作流
前端·后端·visual studio code
SuperEugene22 分钟前
后台权限与菜单渲染:基于路由和后端返回的几种实现方式
前端·javascript·vue.js
兆子龙25 分钟前
WebSocket 入门:是什么、有什么用、脚本能帮你做什么
前端·架构
是一碗螺丝粉29 分钟前
LangChain 链(Chains)完全指南:从线性流程到智能路由
前端·langchain·aigc
月弦笙音34 分钟前
【浏览器】这几点必须懂
前端
青青家的小灰灰35 分钟前
迈向全栈新时代:SSR/SSG 原理、Next.js 架构与 React Server Components (RSC) 实战
前端·javascript·react.js
SuperEugene35 分钟前
弹窗与抽屉组件封装:如何做一个全局可控的 Dialog 服务
前端·javascript·vue.js
UrbanJazzerati36 分钟前
事件传播机制详解(附直观比喻和代码示例)
前端
青青家的小灰灰36 分钟前
透视 React 内核:Diff 算法、合成事件与并发特性的深度解析
前端·javascript·react.js