Vue组件点击事件监控导致性能问题怎么办?

UX红会 阅读 44

在Vue项目里给按钮加了点击监控,发现页面卡顿,代码用了防抖还是没用。这是为什么啊?

我给所有按钮加了统一的点击上报逻辑,代码像这样写的:



  



export default {
  methods: {
    trackClick(type) {
      const debounced = _.debounce(() => {
        window.analytics.track('button_click', { type })
      }, 300)
      debounced()
    }
  }
}

测试时发现明明设置了300ms防抖,但每点击一次都会立即触发上报。更奇怪的是,页面有多个按钮时滚动会卡顿,控制台没报错,这是哪里出问题了?

我来解答 赞 7 收藏
二维码
手机扫码查看
2 条解答
圆圆 ☘︎
问题很明显了,你这个防抖写法每次点击都创建了一个新的debounce实例,当然没用啊。

每次调用trackClick时,const debounced = _.debounce(...) 这行代码都会执行,意思是每次点击都创建了一个全新的防抖函数,这个新函数是"干净"的,没有记录上一次点击的时间,所以会立即执行。

解决方法:把debounced函数放到methods外面去,比如在data里存一份,或者在created钩子里初始化。

export default {
data() {
return {
trackClickDebounced: null
}
},
created() {
this.trackClickDebounced = _.debounce((type) => {
window.analytics.track('button_click', { type })
}, 300)
},
methods: {
trackClick(type) {
this.trackClickDebounced(type)
}
},
beforeDestroy() {
// 组件销毁时清理,防止内存泄漏
if (this.trackClickDebounced) {
this.trackClickDebounced.cancel()
}
}
}


这样同一个按钮的多次点击才会被防抖处理。

关于滚动卡顿的问题,如果你的页面按钮很多很多,建议用事件委托,在父组件上监听一个点击事件,通过e.target来判断点击的是哪个按钮,比每个按钮单独绑一个事件省资源多了。
点赞
2026-03-12 09:12
萌新.自帅
问题在于每次点击都创建了新的防抖函数,导致防抖失效。把防抖函数提到组件外部或者使用单例模式。

改好的代码像这样:

import _ from 'lodash'

const debouncedTrack = _.debounce((type) => {
window.analytics.track('button_click', { type })
}, 300)

export default {
methods: {
trackClick(type) {
debouncedTrack(type)
}
}
}


顺便说下,多个按钮共用一个防抖函数性能会好很多,之前那种写法每点一次就new个新函数,内存占用能不爆才怪。
点赞 9
2026-02-16 04:00