Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

VueJS performance cost of $emit and Watchers

I've built a music app (using Vue and ToneJS) in which the user creates looping tracks which change in various ways according to user choices. This utilizes a rather complex set of scaling counter mechanisms. Having built the musical functionality, I am working on a "progress bar" which shows when the next transition is about to occur.

Currently, the way I am doing this is to calculate the total steps (each note is a 'step') needed and compare it to the progress of each counter (on the Vuex state). In terms of the code, that's a lot of mental overhead.

A better way to do this might be to use $emit to send out a 'tick' each time a step advances, which would be picked up by the component featuring the progress bar and compared to the steps needed. OR, use of a watcher on the component could detect the change and send a tick along.

BUT, I've already run into some timing performance problems with the app, and timing is critical for this. I'm a relatively new dev and don't yet understand performance well. So what I'm wondering is how 'expensive' is it to use $emit, or watchers? Since it would be attached to the 'motor' of the app, it would be called constantly. Is there any danger that this could gum up the gears?

like image 278
drenl Avatar asked Nov 18 '18 19:11

drenl


People also ask

What is the difference between watchers and computed property in VueJS?

Computed props can react to changes in multiple props, whereas watched props can only watch one at a time. Computed props are cached, so they only recalculate when things change. Watched props are executed every time. Computed props are evaluated lazily, meaning they are only executed when they are needed to be used.

How does Vue app measure performance?

Open Developer Tools, and go to Performance tab. Click on “Start Profiling and reload page” (or hit Ctrl + Shift + E). You will see a new section here called User Timing in the performance tab, which should give you a clearer picture of your UI performance.

What are watchers in VueJS?

What is a watcher? A watcher in Vue is a special feature that allows us to observe some data and perform specific actions when it changes. It is a more generic way to observe and react to data changes in the Vue instance.


1 Answers

First, you need to understand what their differences are!

Emitting an event with $emit in vue.js:

Vuejs is using the publish-subscribe pattern for emitting the events. In software architecture, publish–subscribe is a messaging pattern where senders of messages, called publishers, do not program the messages to be sent directly to specific receivers, called subscribers..

Let's visualize this pattern:

Object1 will emit event fooEvent. Other objects might register a subscriber to this event, so whenever any fooEvent event emits the subscribers will be called.

This is how vuejs register subscribers (source code on 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
      }
    }

In a nutshell it just store them in an array vm._events:

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

And this how it calls the subscribers (source-code on 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)
      }

It iterates over all subscribers and calls them one by one in registration order.

So? It doesn't cost anything big!

How watch works?:

Well, it's a long story if we are going to talk about in the source-code but here is the short one:

Whenever you mark a property to be watched inside Vuejs, it runs a big code to watch its changes and schedule it inside a scheduler! SO vue understand the changes by pooling and checking if there is a change or not.

  1. This is how it creates a watcher (every-time you mark an object to be watched, it creates a new Watcher object for it).
  2. The run method inside a watcher will be called by the scheduler.
  3. And how it runs them.

So? It's quite heavy, isn't it?


So the summary of the results and my opinion according to the codes and my personal experience:

Emitting an event isn't such a heavy thing, it's very very lighter than a watcher.

like image 120
Ali Bahrami Avatar answered Oct 23 '22 17:10

Ali Bahrami