Vue 必备性能优化:Lodash防抖与节流实战教程(彻底解决高频请求问题)

2 阅读6分钟

一、前言

在 Vue 项目开发中,输入框实时搜索、页面滚动、按钮频繁点击、窗口缩放等操作,会触发高频事件执行。如果每次触发都直接发起接口请求或执行逻辑,会造成大量无效请求、频繁渲染,极大加重浏览器和服务器压力,导致页面卡顿、性能变差。

Lodash 是前端高频工具库,内置成熟的 debounce(防抖)throttle(节流) 方法,能够优雅限制事件触发频率,是 Vue 项目性能优化的常规主流方案

二、防抖与节流核心原理与场景区分

1. debounce 防抖

核心机制:事件触发后,延迟指定时间执行回调;若延迟期间再次触发事件,会重置计时,直至停止触发、计时走完,才会真正执行一次回调。

通俗理解:连续操作不执行,停下来等一会再执行。

适用场景:输入框实时搜索、窗口大小拖拽缩放、表单实时校验、输入联想查询。

2. throttle 节流

核心机制:事件持续触发时,固定时间间隔内仅执行一次,无论期间触发多少次,都按频率均匀执行,不会无限触发。

通俗理解:持续操作时,每隔一段时间执行一次,匀速限流。

适用场景:页面滚动监听、按钮频繁点击防重、拖拽移动、高频resize监听。

三、Lodash 安装方式

支持 Vue2 / Vue3 全版本,安装命令统一如下:

npm install lodash

使用时按需引入防抖、节流方法,无需全局引入,有效减少项目打包体积,符合轻量化开发规范。

四、Vue2 实战:Lodash 防抖与节流

1. debounce 防抖(输入框实时搜索)

业务场景:输入框实时输入关键词,原生写法每输入一个字符就发起一次请求,产生大量无效请求。防抖优化后,用户持续输入不请求,停止输入300ms后仅执行一次请求,大幅优化性能。

优化说明:移除无效外网测试接口,采用本地模拟数据,代码可直接运行测试,上线后替换真实接口即可。

<template>
  <div class="search-box">
    <input 
      v-model="searchQuery" 
      placeholder="请输入关键词搜索"
    />
    <ul>
      <li v-for="result in searchResults" :key="result.id">
        {{ result.name }}
      </li>
    </ul>
  </div>
</template>

<script>
// 按需引入防抖方法
import { debounce } from 'lodash'

export default {
  data() {
    return {
      searchQuery: '', // 搜索关键词
      searchResults: [], // 搜索结果列表
      // 本地模拟搜索数据源
      searchList: [
        { id: 1, name: 'Vue2 实战教程' },
        { id: 2, name: 'Vue3 语法糖详解' },
        { id: 3, name: 'Lodash 性能优化' },
        { id: 4, name: '前端性能优化指南' }
      ]
    }
  },
  watch: {
    // 监听关键词变化,包裹防抖函数,延迟300ms执行
    searchQuery: debounce(function (newQuery) {
      this.fetchSearchResults(newQuery)
    }, 300)
  },
  methods: {
    // 搜索筛选方法(本地模拟,可直接运行)
    fetchSearchResults(query) {
      // 空关键词清空列表
      if (!query) {
        this.searchResults = []
        return
      }
      // 本地模糊匹配筛选
      this.searchResults = this.searchList.filter(item =&gt; item.name.includes(query))
    }
  }
}
&lt;/script&gt;

2. throttle 节流(页面滚动监听)

业务场景:浏览器滚动会高频触发scroll事件,频繁执行逻辑易造成页面卡顿。通过节流限制执行频率,每300ms仅执行一次逻辑,保证页面滚动流畅。

<template>
  <div>
    <p>当前滚动高度:{{ scrollPosition }}</p>
    <div style="height: 2000px; background: #f0f0f0;">
      滚动页面测试节流效果
    </div>
  </div>
</template>

<script>
// 按需引入节流方法
import { throttle } from 'lodash'

export default {
  data() {
    return {
      scrollPosition: 0,
      scrollHandle: null // 存储节流函数实例,用于销毁取消
    }
  },
  mounted() {
    // 封装节流方法并存储实例
    this.scrollHandle = throttle(function () {
      this.scrollPosition = window.scrollY
    }, 300)
    // 挂载时绑定滚动事件
    window.addEventListener('scroll', this.scrollHandle)
  },
  beforeDestroy() {
    // 组件销毁:移除监听 + 取消防流,彻底释放资源,杜绝内存泄漏
    window.removeEventListener('scroll', this.scrollHandle)
    this.scrollHandle.cancel()
  }
}
</script>

五、Vue3 Setup 语法糖专属写法(主流推荐)

Vue3 组合式API + setup语法糖是目前项目主流写法,适配Vue3全版本,代码更简洁、逻辑更集中,下面提供可直接上线的防抖、节流完整案例,全部适配本地测试,无接口依赖。

1. Vue3 防抖实战(实时搜索)

<template>
  <div class="search-box">
    <input v-model="searchQuery" placeholder="Vue3 防抖搜索" />
    <div v-for="item in searchList" :key="item.id">{{ item.title }}</div>
  </div>
</template>

<script setup>
import { ref, watch } from 'vue'
// 按需引入lodash防抖
import { debounce } from 'lodash'

// 定义响应式数据
const searchQuery = ref('')
const searchList = ref([])
// 本地模拟数据源
const sourceData = ref([
  { id: 1, title: 'Vue3 组合式API' },
  { id: 2, title: 'Lodash 防抖节流' },
  { id: 3, title: '前端性能优化' },
  { id: 4, title: 'Vue项目实战优化' }
])

// 封装搜索筛选方法(本地模拟,可直接运行)
const getSearchData = (val) => {
  if (!val) {
    searchList.value = []
    return
  }
  // 本地模糊匹配
  searchList.value = sourceData.value.filter(item => item.title.includes(val))
}

// 防抖监听:延迟300ms执行,避免高频触发
const debounceSearch = debounce(getSearchData, 300)
watch(searchQuery, (newVal) => {
  debounceSearch(newVal)
})
</script>

2. Vue3 节流实战(滚动监听+按钮防重)

包含两大高频场景:页面滚动节流、按钮重复点击节流,完美解决Vue3项目高频操作性能问题,自带销毁逻辑,零内存泄漏。

<template>
  <div>
    <p>页面滚动高度:{{ scrollTop }}</p>
    <button @click="submitHandle">提交表单(节流防重)</button>
    <div style="height: 2000px;background: #f5f5f5;margin-top: 20px;">滚动测试区域</div>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted } from 'vue'
import { throttle } from 'lodash'

const scrollTop = ref(0)

// 1. 滚动节流函数 300ms执行一次
const scrollHandle = throttle(() => {
  scrollTop.value = window.scrollY
}, 300)

// 2. 按钮点击节流 1s内仅可点击一次(防重复提交)
const submitHandle = throttle(() => {
  console.log('执行表单提交逻辑,请求接口')
  // 可在此处写接口请求、表单提交等业务逻辑
}, 1000)

// 挂载绑定事件
onMounted(() => {
  window.addEventListener('scroll', scrollHandle)
})

// 销毁移除事件,杜绝内存泄漏
onUnmounted(() => {
  window.removeEventListener('scroll', scrollHandle)
  // 取消节流监听,释放资源
  scrollHandle.cancel()
})
</script>

3. Vue3 核心注意点

  • Vue3 setup语法中,防抖/节流函数需单独封装变量接收,避免直接写在watch内部导致销毁异常、逻辑失效
  • 高频全局事件(scroll、resize),必须在 onUnmounted 中移除监听、调用 cancel() 取消节流防抖
  • 按钮防重提交推荐设置 1000ms 节流间隔,有效防止用户快速重复点击、重复提交表单
  • 支持调用 cancel() 方法手动取消防抖/节流,灵活适配弹窗关闭、页面跳转等复杂业务场景

六、防抖 & 节流核心总结

方法执行逻辑核心特点常用场景
debounce 防抖停止操作后延迟执行,连续操作重置计时多次触发,只执行最后一次搜索框联想、输入校验、窗口缩放
throttle 节流固定间隔匀速执行,持续触发不叠加限定频率,间隔执行页面滚动、按钮防重、拖拽操作

七、开发避坑与最佳实践

  • 场景区分:高频输入联想、实时校验用防抖;持续触发的滚动、点击、拖拽事件用节流
  • 时间规范:常规防抖/节流延迟默认 300ms,按钮防重、表单提交推荐 1000ms
  • 内存优化(重中之重) :所有全局绑定的高频事件,组件销毁必须移除监听、手动 cancel 取消防抖节流,彻底杜绝内存泄漏
  • 写法规范:Vue3 优先使用组合式API单独封装防抖节流函数,代码解耦、方便销毁、更易维护
  • 性能最优:优先按需引入lodash单个方法,不全局导入整个库,有效减小项目打包体积
  • 测试规范:本地开发优先使用模拟数据测试功能,上线后替换真实业务接口,避免无效接口报错
  • 手动取消:弹窗关闭、页面跳转、数据重置场景,可主动调用 cancel() 终止防抖节流监听,避免无效执行