简体   繁体   中英

Comparing computed vs a copy (Vue js)

I've asked the question here: https://forum.vuejs.org/t/comparing-computed-vs-a-copy/34542 , and am not getting any traction.

TL;DR Using Vue JS computed seems to re-evaluate for properties that the computed doesn't depend on.

Below is a jsfiddle showing an oddity (maybe explainable) that I've encountered with computeds.

Original: https://jsfiddle.net/1v58dj8x/3/

With Roy's suggestions: https://jsfiddle.net/1v58dj8x/4/

Vue js properties:

data:
    {
        items: [],
        copy: [],
        starti: 0,
        endi: 100,
        total: 5000
    },

The example shows two graphs with the same data. One is a computed (of items) and another is just a copy of a larger data set (also items). I would assume that during access and without its dependencies changing, the computed should be just as fast as a copy of the same data.

In fact it is if one just calls points() over and over. However, if I change starti or endi, then it seems that vue is re-evaluating the underlying dependencies (items). I don't understand why this is. I would expect it to not re-evaluate as starti and endi are not (to my eye) dependencies.

The second issue I have with this, is that the first computed run takes a very long time. However, it's less of a concern as initial loading is easily concealed with a loading animation.

If one changes the number of data points (ie mess with total), you can see the difference in time on both access and load isn't linear. In a couple of projects, I have just stuck with the copy of the data in favor of speed, but I'd like clarity here as I could most likely not be using this library (Vue js) correctly.

I got a tremendous initial speedup by rewriting filter :

        filter: function()
        {
            let ret = this.items
              .filter((i) => i.type === 'criteria')
              .map((i) => ({name: i.name, value: i.value}));

            return ret;
        },

It looks like indexing operations on observable (computed or not) arrays are fairly expensive.

This also performed well:

    filter: function() {
      let ret = [];

      this.items.forEach((item) => {
        if (item.type == 'criteria')
          ret.push({
            'name': item.name,
            'value': item.value
          });
      });

      return ret;
    },

I also modified points to stop indexing filtereditems (see the first and last lines here):

      const items = this.filtereditems;
      for (let i = this.starti; i < end; ++i) {
        let x = i * 5 + 100;
        let y = items[i].value + 200;

and points is now faster than points4copy . (Editing points4copy in the same way speeds it up, too.)

The lesson: avoid indexing observable arrays.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM