防抖与节流

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

五、口诀

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

总结

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

✅ 用对 = 页面丝滑如丝绸

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

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

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


总结

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

✅ 用对 = 页面丝滑如丝绸

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

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

相关推荐
小李子呢02111 天前
前端八股6---v-model双向绑定
前端·javascript·算法
He少年1 天前
【基础知识、Skill、Rules和MCP案例介绍】
java·前端·python
史迪仔01121 天前
[QML] QML IMage图像处理
开发语言·前端·javascript·c++·qt
AwesomeCPA1 天前
Miaoduo MCP 使用指南(VDI内网环境)
前端·ui·ai编程
前端大波1 天前
前端面试通关包(2026版,完整版)
前端·面试·职场和发展
qq_433502181 天前
Codex cli 飞书文档创建进阶实用命令 + Skill 创建&使用 小白完整教程
java·前端·飞书
IT_陈寒1 天前
为什么我的Vite热更新老是重新加载整个页面?
前端·人工智能·后端
一袋米扛几楼981 天前
【网络安全】SIEM -Security Information and Event Management 工具是什么?
前端·安全·web安全
小陈工1 天前
2026年4月7日技术资讯洞察:下一代数据库融合、AI基础设施竞赛与异步编程实战
开发语言·前端·数据库·人工智能·python