VueJS中$emit和Watchers的性能成本

8
我使用Vue和ToneJS构建了一个音乐应用程序,用户可以创建循环轨道,并根据用户选择以各种方式进行更改。这需要使用一组相当复杂的缩放计数器机制。在构建了音乐功能之后,我正在开发一个“进度条”,用于显示下一个转换即将发生的时间。
目前,我是通过计算所需的总步骤(每个音符都是一个“步骤”)并将其与每个计数器的进度(在Vuex状态上)进行比较来完成此操作。就代码而言,这需要耗费大量精力。
更好的方法可能是使用$emit,每次步骤推进时发送一个“tick”,该“tick”将被包含进度条的组件接收并与所需步骤进行比较。或者,在组件上使用watcher检测更改并发送一个“tick”。
但是,我已经遇到了一些应用性能方面的问题,而且对于这个应用程序来说,时间非常重要。我是一位相对较新的开发人员,还不太了解性能。因此,我想知道使用$emit或观察程序是否会很“昂贵”。由于它将附加到应用程序的“引擎”上,因此将被不断调用。有没有可能这会导致性能下降?

抛出事件并不是代价高昂的,处理才是。有助于提高性能的方法是:a)确保只在必要时触发事件;b)在处理过程中(监听事件时)使用廉价条件,如果不必要则停止处理。如果我可以给你建议:当性能真正成为问题时再去关注它。请记住,性能还取决于运行应用程序的客户端计算机的计算能力(例如,您的用户计算机)。 - Marc Dix
我知道有点晚了,但我还是尽力为你描述了一下。 - Ali Bahrami
1个回答

18

首先,你需要理解它们的区别!

vue.js中使用$emit触发事件:

Vuejs使用发布-订阅模式来触发事件。 在软件架构中,发布-订阅是一种消息传递模式,发送消息的发送者(称为发布者)不直接将消息编程发送给特定的接收者(称为订阅者)。

让我们来可视化这个模式:

对象1将会触发事件fooEvent。其他对象可能会注册该事件的订阅者,因此每当任何fooEvent事件被触发时,都会调用这些订阅者。

这就是vuejs如何注册订阅者的方式(Github上的源代码):

  Vue.prototype.$on = function (event: string | Array<string>, fn: Function): Component {
    const vm: Component = this
    if (Array.isArray(event)) {
      for (let i = 0, l = event.length; i < l; i++) {
        vm.$on(event[i], fn)
      }
    } else {
      (vm._events[event] || (vm._events[event] = [])).push(fn)
      // optimize hook:event cost by using a boolean flag marked at registration
      // instead of a hash lookup
      if (hookRE.test(event)) {
        vm._hasHookEvent = true
      }
    }

简而言之,它只是将它们存储在一个数组vm._events中:

(vm._events[event] || (vm._events[event] = [])).push(fn)

这是它调用订阅者的方式(Github上的源代码):

    let cbs = vm._events[event]
    if (cbs) {
      cbs = cbs.length > 1 ? toArray(cbs) : cbs
      const args = toArray(arguments, 1)
      const info = `event handler for "${event}"`
      for (let i = 0, l = cbs.length; i < l; i++) {
        invokeWithErrorHandling(cbs[i], vm, args, vm, info)
      }

它迭代遍历所有订阅者并按注册顺序依次调用它们。

那又怎样呢?这不需要花费太大的代价!

观察者模式是如何工作的?:

如果我们要在源代码中讨论,这就是一个漫长的故事,但这是简短的版本:

每当你在Vuejs中标记一个属性以进行观察时,它会运行大量代码来观察其更改并将其安排在调度程序中!因此vue通过汇集和检查是否有更改来理解更改。

  1. 这就是每次标记要观察对象时它如何创建观察程序(对象)。
  2. 观察程序内的run方法将由调度程序调用
  3. 以及它如何运行它们。

那么结果如何?很重吗?


因此,根据代码和我的个人经验,总的结果和意见如下:

发出事件并不是什么很重的事情,比观察者要轻得多。


这个答案对Vue3仍然适用吗? - Xaver Fleer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接