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
Major Performance Change - Re-Use Expensive To Generate Data #277
Conversation
…quals. Re-use expensive to generate objects rather than regenerating, allow us to use shallowEqual instead of expensive deepEqual for comparison
…e to generate items
…ts for shallowEqual to reflect new behavior
…rt, LineChart, and Pie Chart to speed up re-renders.
…or for Area, Bar,Line, and Composed Chart. Change lint one-var-declaration-per-line and fix resulting lint errors
…stead of new props, causing stale rendering. This fixed an issue with brushes not working propertly. Also reverted istanbul-instrumenter-loader package as it was throwing an error with the new 1.0 version
I may add more tests, but the bulk of the functionality for this pull request is complete. Please review and merge or give feedback on what you'd like changed. |
…sts for chart when brush changes to make sure points update appropriately
I added tests that would have caught my earlier errors:
|
…n LineCharts, which should help catch issues with several others as well
I added tests to future proof against pure rendering getting messed up by checking that mouse enter/move and brush movement that doesn't actually change the start/end index on a LineChart do not cause a re-render of the Line child component. |
@billneff79 Thanks for your contribution. It's really awesome. I'll review all the commits an soon as possible. |
@billneff79 if you fix the conflicts maybe this can go through then? |
I fixed all of the conflicts and all of the tests still pass. I had to artisanally merge the last change from BarChart to get maxSize in, but I think it came out OK ;) |
These three methods are always topping my profiles, because they perform a ton of unnecessary Object cloning. Instead of cloning on each iteration of a loop, I've eliminated it altogether and removed all the closures.
I added two more commits from our fork that are performance related. I think that's it for these performance changes. |
On a side note, we've effectively abandoned recharts for our project, after we had made some interesting changes to it. You may want to pull them in from our fork. Let me know if you need any help. You can look at the commits after October 3rd, 2016 to get an idea of what we added: https://github.com/billneff79/recharts/commits/master Highlights include:
|
\o/ |
@billneff79 Thank you for your contribution. It's really awesome.👍 We'll consider about your commits in your master. |
Other performance tips you might want to try for big data sets that we've seen tremendous (4-5x performance boost) results from include: Don't plot more than one data point per css pixel. i.e. if you have 1000 data points, but your graphable width in your chart is only 300 pixels, you will waste a lot of cpu calculating the path for your chart without being able to see 2/3rds of it. So, we just pruned the data when generating the ticks for our area/line/etc. charts to get it down to 1 point max per pixel: i.e. if there are 3 times as many points as pixels, we generate the graph from data[0], data[3], data[6], data[9], .... As the user uses a Brush to zoom in on the graph, we re-calculate the data points used for drawing the path, so you can get to full data fidelity on the graph as soon as you zoom into a view where there is at least one point per pixel. It turns out that it's just way faster to prune the data on each Brush movement than it is not render a full, but overly granular, path |
@billneff79 You are a champion. Thank you for all this insight and your contribution to the repo. |
You're very welcome! On Tuesday, November 1, 2016, Sean Bullock notifications@github.com wrote:
|
@billneff79 thanks mate! |
Recharts, prior to this pull request, wasn't taking full advantage of React's rendering optimizations for sub-trees. The "shallowEqual" function in PureRender was actually a deep-equal, which was very expensive and re-computed several times on any given event (e.g. mouse moving over the graph).
Part of the reason a deep equality was likely used was that some of the props, like the axis maps and ticks were being generated as brand new object on every render, even though the data in them was the same, so a shallow equality would have failed.
In a nutshell, this pull request does two things:
All-in-all, it is significantly faster now. lint checks and tests all pass.
Note for future: In running the automated tests and comparing against manual test restuls, I had bugs that I manually found and fixed that weren't failing in any automated tests. We should add test cases for: