防抖与节流

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

五、口诀

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

总结

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

✅ 用对 = 页面丝滑如丝绸

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

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

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


总结

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

✅ 用对 = 页面丝滑如丝绸

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

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

相关推荐
宇珩前端踩坑日记2 小时前
怎么让 Vue DevTools 用 Trae 打开源码
前端·trae
小徐不会敲代码~2 小时前
Vue3 学习 6
开发语言·前端·vue.js·学习
CreasyChan2 小时前
C#中单个下划线的语法与用途详解
前端·c#
C_心欲无痕2 小时前
react - useState更新机制(直接更新和函数式更新)
前端·javascript·react.js
@AfeiyuO2 小时前
Vue3 饼图定制图
vue·echarts
GDAL2 小时前
Tailwind CSS 菜单实现全面讲解教程(基于书签篮网站场景)
前端·css·菜单
m5655bj2 小时前
如何通过 C# 实现 PDF 页面裁剪
前端·pdf·c#
这是个栗子2 小时前
前端开发中的常用工具函数(持续更新中...)
前端·javascript·算法
zhangsansecond2 小时前
vs创建 基于ASP.NET Framework 的 SOAP 协议 Web 服务,https无法访问
前端·https·asp.net