Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

very poorly performance on computed property of computed property that accesses a nested array #6660

Closed
SeregPie opened this issue Sep 21, 2017 · 4 comments

Comments

@SeregPie
Copy link

Version

2.4.4

Reproduction link

https://jsfiddle.net/kz16r91L/

Steps to reproduce

First computed property accesses a nested array and second computed property accesses the first computed property.

What is expected?

The computed property is cached and the repeated calls returns the result immediately.

What is actually happening?

The compute function is not called but each access to the computed property is very slow.


Looks like the computed property, that accesses a nested array, is not cached properly.

@yyx990803
Copy link
Member

This is related and explained in #6284

For now, you can avoid the iteration cost by freezing the Array, if you don't expect it to be mutated. This will no longer be necessary in 3.0 though.

@SeregPie
Copy link
Author

SeregPie commented Sep 22, 2017

Wait. This is not the cause. The cause is, that the access to an already computed property is very slow. If you put a watcher between two computed properties, then all is working great.
See testBB is now even faster than testAA.
I also did the same in my project and all the changes are still reflected properly, but it is a million times faster.

@Akryum
Copy link
Member

Akryum commented Sep 22, 2017

@SeregPie Your test is wrong because the watcher is called before it: https://jsfiddle.net/ns1n6kwq/1/ I also added a few tests:

  • The second one access the cached values and it is very performant as expected.
  • The third one adds a new object into the base object property. As you can see, the value of testBB is not the correct final value in your test, because the watcher hasn't fired yet. In reality, you are still accessing the cached value (and as such you get the same super fast access to the value).

vue-issue-6660

So the results of your test are incorrect and make your think the watcher is called instantly. Also, you are not using deep: true which make your watcher not detecting the potential changes in the nested arrays (unlike the computed property which does by default), so the comparison is wrong too.


The performance issue comes from Vue building the dependencies when evaluating the computed properties: accessing the computed properties multiple times adds even more dependencies and slows down the component.

One thing I did when having this kind of performance heavy computed properties was to just access the computed property once and assign it into a local variable:

myComputed () {
  const a = this.myOtherComputed
  // use a instead of this.myOtherComputed
}

Example for my proposed solution: https://jsfiddle.net/kLor5ep7/1/

You may find that this is in fact as performant as using a watcher as you can see in this corrected version of your watcher test: https://jsfiddle.net/LrLqmmjr/1/ (The watcher is manually added after the first evaluation of the pTestB computed property so the times are right. It is not added again in the next tests. Also, there is a little overhead compared to the previous without-watcher code because the watcher timer includes the call to test and the Promise constructor.)
Notice the time taken by the watcher to fire and update testB after the new element is added to the array.

tl;dr

Inside your computed properties, use local variables to store the other computed properties and avoid accessing them directly multiple times.

@mciesin
Copy link

mciesin commented Nov 12, 2019

Did someone come up with a solution for the use case, when the problem of a slowdown is accessing such computed property in multiple components (instead of having multiple accesses to a computed in another computed) 😅?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants