victory icon indicating copy to clipboard operation
victory copied to clipboard

[Performance] frame rate drops when zooming on large data sets

Open petermikitsh opened this issue 8 years ago • 17 comments

Hi, I tried swapping out d3 for victory for the SSR support. (I was able to write dramatically less code, which is awesome 👍 ).

Everything looks great, except for a performance issue I encountered. I made a VictoryLine with a data set of ~1,000 (x, y) points and I'm seeing low frame rates in victory (~6 fps) I wasn't observing with d3 (~60 fps). Here's the code (lightly edited):

import VictoryChart from 'victory-chart/es/components/victory-chart/victory-chart';
import VictoryLine from 'victory-chart/es/components/victory-line/victory-line';
import VictoryZoomContainer from 'victory-chart/es/components/containers/victory-zoom-container';

let dates = [
  Number(new Date(2017, 6, 11, 3, 24, 0)),
  Number(new Date(2017, 6, 12, 1, 24, 0)),
  Number(new Date(2017, 6, 13, 7, 24, 0)),
  Number(new Date(2017, 6, 14, 2, 24, 0)),
  Number(new Date(2017, 6, 15, 11, 44, 0))
];

for (let i = 0; i <= 1000; i += 1) {
  dates.push(Number(new Date(2017, 6, 15, 11, 44, 0)));
}

const data = dates.reduce((array, date) => {
  let cumulative = 1;
  if (array.length > 0) {
    cumulative += array[array.length - 1].y;
  }
  array.push({
    x: date,
    y: cumulative
  });
  return array;
}, []);

function VictoryChartWithLotsOfData() {
  return (
    <VictoryChart
      scale={{ x: 'time'}}
      containerComponent={
        <VictoryZoomContainer
          dimension="x"
        />
      }
    >
      <VictoryLine
        data={data}
      />
    </VictoryChart>
  );
}

Renders were about ~6 fps. Here's a screenshot of the performance tab in Chrome dev tools:

screen shot 2017-07-16 at 4 42 57 pm

And the animation itself. You can observe the dropped frames in the x-axis labels:

framedrop

This performance issue would block me from adopting Victory today, but it's something I think can be fixed. Otherwise, it is 100% what I'm looking for.

petermikitsh avatar Jul 16 '17 23:07 petermikitsh

Hey @petermikitsh! I'm so glad you brought this up. It's been a pet project of mine to address this. We have a new guide that shows how to render 10,000 points with the ZoomContainer efficiently. The guide still isn't published on our docs (sorry, i'm fighting a few fires today :P) but you can read it here: https://github.com/FormidableLabs/victory-docs/blob/master/src/screens/guides/components/zoom-large-data/ecology.md

demo here: http://jsfiddle.net/chrisbolin/ufn9xtub/

chrisbolin avatar Jul 18 '17 18:07 chrisbolin

@chrisbolin I like the solution you propose because it addresses the issue, but architecturally, shouldn't these problems be the responsibility of the library, probably somewhere in the VictoryZoomContainer implementation? It should be performant with 1,000 data points without having to hack it.

petermikitsh avatar Jul 18 '17 19:07 petermikitsh

@petermikitsh i think you're completely right. i'm in the middle of creating an issue for that exact thing :)

chrisbolin avatar Jul 18 '17 19:07 chrisbolin

but i wouldn't hold out for a solution, because I don't know how involved a fix will be (e.g. do we address just this use-case, or do we do something more general)

chrisbolin avatar Jul 18 '17 19:07 chrisbolin

meaning, if you can use that demo, i would go with that for now 👍

chrisbolin avatar Jul 18 '17 19:07 chrisbolin

@chrisbolin Awesome, thank you! The work around is sufficient for the time being. I opened up dev tools and confirmed the frame rates stays near 60 frames / second.

petermikitsh avatar Jul 18 '17 19:07 petermikitsh

perfect! that's awesome. I'll reference this issue in my new Address large data problems issue (this has come up a lot lately, hence why I've been thinking about it). But again, I wouldn't wait for that fix if I were you, because it could take a while to address all the various issues and user preferences. Thanks for your patience with Victory :)

chrisbolin avatar Jul 18 '17 19:07 chrisbolin

Hey @petermikitsh! I'm so glad you brought this up. It's been a pet project of mine to address this. We have a new guide that shows how to render 10,000 points with the ZoomContainer efficiently. The guide still isn't published on our docs (sorry, i'm fighting a few fires today :P) but you can read it here: https://github.com/FormidableLabs/victory-docs/blob/master/src/screens/guides/components/zoom-large-data/ecology.md

demo here: http://jsfiddle.net/chrisbolin/ufn9xtub/

@chrisbolin The Github link is directing to a 404 not found error page

arulyan avatar Jul 14 '22 16:07 arulyan

Okay I think I was able to get that from the updated docs : HERE I implemented the zoom/brush functionality for React Native (Mobile Application), the performance is very laggy. It works well only with the web application.

arulyan avatar Jul 14 '22 18:07 arulyan

@arulyan Were you able to improve the performance in React Native? I implemented a fairly "simple" graph, although with a lot of axis/decoration. But with a rather limited amount of points (~100).

I added a VictoryZoomContainer and disabled zooming (only allow pan). As per documentation i also implemented the onZoomDomainChanged method to filter the nr. of points based on the visible area of the domain.

And the performance is still really bad. Only on iOS it seems somewhat acceptable (but has a lagging feel anyhow). On Android it is really bad, with a low frame rate.

I assume you are correct in your evaluation that it only works properly on web? Although I haven't been able to test on web myself yet.

For what it is worth, the video below uses 2 VictoryLine components, 1 VictoryScatter component, 7 VictoryAxis components and 3 VictoryArea components.

https://user-images.githubusercontent.com/135126/186880878-e2238a86-0a1a-41c9-a43f-9ebbd1f5beb3.mp4

bitcrumb avatar Aug 26 '22 10:08 bitcrumb

If you just need scrolling behavior, it is actually more performant to render out the whole chart inside a scrollview, and draw a separate fixed axis next to it (outside the scrollview).

In essence I am rendering out two VictoryChart instances here:

  • one with all the data & axises (except for the right axis)
  • and one with only the right axis

See video:

https://user-images.githubusercontent.com/135126/186923140-2ad1a247-bc1d-49ef-98a3-2468067724dc.mp4

This is day and night in terms of scrolling performance + it has a more native feel on iOS & Android.

bitcrumb avatar Aug 26 '22 14:08 bitcrumb

any update in this?

Eramirez06 avatar Dec 27 '22 05:12 Eramirez06

If you just need scrolling behavior, it is actually more performant to render out the whole chart inside a scrollview, and draw a separate fixed axis next to it (outside the scrollview).

In essence I am rendering out two VictoryChart instances here:

  • one with all the data & axises (except for the right axis)
  • and one with only the right axis

See video:

ios_native_scrollview.mp4 This is day and night in terms of scrolling performance + it has a more native feel on iOS & Android.

Hi. @bitcrumb Can you show me the source code? Thank^^

kokokj124 avatar Sep 15 '23 08:09 kokokj124

If you just need scrolling behavior, it is actually more performant to render out the whole chart inside a scrollview, and draw a separate fixed axis next to it (outside the scrollview).

In essence I am rendering out two VictoryChart instances here:

  • one with all the data & axises (except for the right axis)
  • and one with only the right axis

See video:

ios_native_scrollview.mp4 This is day and night in terms of scrolling performance + it has a more native feel on iOS & Android.

that's really clever, unfortunately on my case my graph has live data, so to use this approach I'll need to rerender the left graph each second, I also need the zoom feature so it's been hell to improve the performance on that...

iujisato avatar Nov 23 '23 13:11 iujisato

Which good brother can help me check out the problem with this animation: https://github.com/FormidableLabs/victory/issues/2823

hangyangws avatar Feb 28 '24 02:02 hangyangws

Right now we use a combination of React and CSS to perform animations instead of using d3 directly. This causes a lot of performance issues due to the amount elements that are created and manipulated. We have plans to change the animation engine entirely to d3 animations. This is on the roadmap after we complete our current upgrades of babel/webpack and other deps that open up more modern tools for us.

carbonrobot avatar Feb 28 '24 15:02 carbonrobot

en~ Is there any way could solve this problem in issue 2823?

hangyangws avatar Feb 29 '24 09:02 hangyangws