Devextreme-reactive: Chart with 30+ series becomes very slow

Created on 24 Sep 2020  路  6Comments  路  Source: DevExpress/devextreme-reactive

  • [x ] I have searched this repository's issues and believe that this is not a duplicate.

I'm using ...

  • [ ] React Grid
  • [x] React Chart
  • [ ] React Scheduler

Current Behaviour


As I add more and more series to a chart dynamically it becomes more and more slower and unresponsive.

Expected Behaviour


Number of series shouldn't affect performance so much.

Steps to Reproduce


Video (original version)
Video (fixed version)

Fix: PluginHost.collect()

original version:

  collect(key, upTo?) {
    if (this.validationRequired) {
      this.ensureDependencies();
      this.validationRequired = false;
    }

    if (!this.gettersCache[key]) {
      this.gettersCache[key] = this.plugins.map(plugin => plugin[key]).filter(plugin => !!plugin);
    }
    if (!upTo) return this.gettersCache[key];

    const upToIndex = this.plugins.indexOf(upTo);
    return this.gettersCache[key].filter((getter) => {
      const pluginIndex = this.plugins.findIndex(plugin => plugin[key] === getter);
      return pluginIndex < upToIndex;
    });
  }

fixed version:

  collect(key, upTo?) {
    if (this.validationRequired) {
      this.ensureDependencies();
      this.validationRequired = false;
    }

    if (!this.gettersCache[key]) {
      this.gettersCache[key] = this.plugins.map(plugin => plugin[key]).filter(plugin => !!plugin);
      // Add cache for original plugin indexes
      this.gettersCache[key + 'index'] = this.plugins.map((plugin, index) => ({ key: plugin[key], index})).filter((plugin) => !!plugin.key; );
    }
    if (!upTo) return this.gettersCache[key];

    const upToIndex = this.plugins.indexOf(upTo);
    const indexCache = this.gettersCache[key + 'index'];
    return this.gettersCache[key].filter((getter, index) => {
      // const pluginIndex = this.plugins.findIndex(plugin => plugin[key] === getter);
      const pluginIndex = indexCache[index].index;
      return pluginIndex < upToIndex;
    });
  }

Screenshots

Environment

  • devextreme-reactive: 2.7.0
  • react: 16.13.1
  • browser: Chrome/85.0.4183.121
  • bootstrap: none
  • react-bootstrap: none
  • material-ui: 4.11.0
Chart question

All 6 comments

I think better version with upTo cache

  collect(key, upTo?) {
    if (this.validationRequired) {
      this.ensureDependencies();
      this.validationRequired = false;
    }

    let res = this.gettersCache[key];
    if (!res) {
      res = this.plugins.map(plugin => plugin[key]).filter(plugin => !!plugin);
      this.gettersCache[key] = res;
      // Add cache for original plugin indexes
      this.gettersCache[key + 'index'] = this.plugins.map((plugin, index) => ({ key: plugin[key], index})).filter((plugin) => !!plugin.key; );
    }
    if (!upTo) return res;

    const upToIndex = this.plugins.indexOf(upTo);

    let upToRes = this.gettersCache[key + upToIndex];
    if (!upToRes) {
      const indexCache = this.gettersCache[key + 'index'];
      upToRes = this.gettersCache[key].filter((getter, index) => {
        const pluginIndex = indexCache[index].index;
        return pluginIndex < upToIndex;
      });
      this.gettersCache[key + upToIndex] = upToRes;         
    }
    return upToRes;
  }

Hi @ajsergeev,

Thank you so much for your great research and work. We will be happy to apply your code changes. Would you like to be our contributor and make a PR yourself?

Hi @MaximKudriavtsev,
I will try to do it ASAP.
Thanks!

@MaximKudriavtsev
Hi, Maxim!
Is there any ETA when this fix will be available?
We have release soon and I need to give some estimate to my management,
if it's not soon then I can tweak it in some other way temporary.
Thanks!

Hi @ajsergeev,

Thank you for your participation. I merged your great PR and started preparing for the release. I think a new NPM package will be available at the end of the week.

Hi @ajsergeev,

We have released the 2.7.2 version of DevExtreme Reactive with this fix.

Was this page helpful?
0 / 5 - 0 ratings