防抖与节流

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

五、口诀

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

总结

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

✅ 用对 = 页面丝滑如丝绸

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

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

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


总结

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

✅ 用对 = 页面丝滑如丝绸

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

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

相关推荐
子兮曰3 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰3 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万3 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝3 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋3 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
卡布鲁3 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
汉堡大王95273 天前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端
梦想很大很大3 天前
从运行事实到回归证据:Workrun 的 Telemetry 与 Evaluation 实践
前端·人工智能·后端
计算机魔术师3 天前
Meta Muse agent 接入 Shopify 的 Shop Pay 实现代理式购物
前端
沙蒿同学3 天前
我用 Go 搭了一条 AI Agent 流水线:从 1 张商品图到一整套淘宝详情页
前端·javascript·后端