Skip to content

Mitigate memory and performance issues for very large lists. - #1343

Closed
omerts wants to merge 7 commits into
bvaughn:masterfrom
omerts:mitigate-out-of-memory
Closed

omerts wants to merge 7 commits into
bvaughn:masterfrom
omerts:mitigate-out-of-memory

Conversation

@omerts

@omerts omerts commented Mar 6, 2019

Copy link
Copy Markdown

Current implementation of CellSizeAndPositionManager is prune to out of memory exceptions and laggy behavior when dealing with very large lists. Specifically this is due to the fact that many cells sizes are calculated, and stored in cache, causing a memory bloat, and slower performance. This pull request mitigates the issue in cases where the CellSize is a numeric value, so at least there is a way of working with very large lists. It does so, by arithmetically calculating offsets, size, and position. As the size is static for every cell there is no need to iterate over other cells to figure out these values.

It can be easily reproduced in the demo just by raising the List's number of rows to 40 million items, and pulling the scroll down.

Before the fix (pull scroller down was also laggish):
image

After fix (scroller was very responsive):
image

Omer Tsvi Spalter added 7 commits February 26, 2019 12:21
	- There is no real benefit in creating the wrapper function
	- Before the change, the Grid component holds logic related only
	  to CellSizeAndPositionManager
	- Having the actual defined cell size is needed
	  for better calculating the offset
Holding a cache of cell sizes can have a memory hit in case of very
large lists, especially if the user scrolls to a deep page. This
mitigates the issue in case the CellSize is a numeric value. In such
a case, instead of calculating the size of all cells up to the wanted
index and caching the results, we simply multiply the index by the height.
Use the new added numeric cell size for:
	- Getting the total size in a precise, independent, performance better way.
	- Finding nearest cell, without having to run into edge cases
	  when cells weren't measured yet
Update existing unit tests for passing a numeric, or thunk CellSize.
Cleanly duplicate some tests for testing both methods.
@eladhayun

Copy link
Copy Markdown

👍 need this ASAP, hope will be merged soon


_isCellSizeNumeric(): number {
return typeof this._cellSize === 'number';
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't feel like you would need to remove this. Is there any specific reason?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it was due to flow type error

@tomasro27

tomasro27 commented Apr 10, 2019 •

Copy link
Copy Markdown

@omerts
Does this PR fixes the issue when there are columns with different width, or would it only work in the case that cells have a fixed height/width?

Also, this is optimizing the calculation of the cell sizes, but it doens't change the way caching is done, correct?

For very large grids, dragging the scrollbar makes the grid crash out of memory. However, doing different scrolling events with the mouse doesn't cause this, because the cache is cleared after every scroll event. I was wondering if it is worth adding more logic to the cell and style caches to avoid this, when scrolling through millions of rows.

@omerts

omerts commented Apr 18, 2019 •

Copy link
Copy Markdown
Author

@tomasro27 Sorry for the late response.

Does this PR fixes the issue when there are columns with different width, or would it only work in the case that cells have a fixed height/width?

It only fixes the issue for fixed width/height. That's why I only called it "mitigate" the issue.

Also, this is optimizing the calculation of the cell sizes, but it doens't change the way caching is done, correct?

Correct, since it does all calculation with arithmetic operation there is no need for a cache.

For very large grids, dragging the scrollbar makes the grid crash out of memory. However, doing different scrolling events with the mouse doesn't cause this, because the cache is cleared after every scroll event. I was wondering if it is worth adding more logic to the cell and style caches to avoid this, when scrolling through millions of rows.

IMHO if cache is cleared on every scroll event this is even a greater reason to add this. If you keep on scrolling down, and cache is invalidated, the component will have to recalculate all the cells up to the current cell every time. This will fix this issue for fixed size rows/columns. Also, dragging the scrollbar is a necessity if for large lists when you want to scan through them. Not having this, is kind of like having a video player that only allows you to seek with 15 seconds jumps, and not be able to seek with the mouse to the middle.

@hieuhlc

hieuhlc commented May 25, 2019

Copy link
Copy Markdown

Hi @omerts @tomasro27 can I ask the progress of this issue? It seems very promising...

@TheBox193

Copy link
Copy Markdown

What would it take to move this forward?

@dannyseo517

Copy link
Copy Markdown

Can we get an update on this? I'm Dealing with 200 million rows and it would be awesome to move this forward.

@wuweiweiwu wuweiweiwu closed this Nov 13, 2019
@wuweiweiwu wuweiweiwu reopened this Nov 13, 2019
@codecov-io

Copy link
Copy Markdown

Codecov Report

Merging #1343 into master will decrease coverage by 0.03%.
The diff coverage is 90%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1343      +/-   ##
==========================================
- Coverage   90.39%   90.35%   -0.04%     
==========================================
  Files          59       59              
  Lines        1738     1752      +14     
==========================================
+ Hits         1571     1583      +12     
- Misses        167      169       +2
Impacted Files Coverage Δ
source/Grid/Grid.js 94.38% <ø> (-0.06%) ⬇️
...ce/Grid/utils/ScalingCellSizeAndPositionManager.js 90.9% <ø> (ø) ⬆️
source/Grid/utils/CellSizeAndPositionManager.js 92.38% <90%> (-0.81%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update fb3484e...1ac08bd. Read the comment docs.

@arsnyder16

Copy link
Copy Markdown

@omerts @wuweiweiwu @tomasro27 @bvaughn Where does this stand? What needs to be done to move this forward?

We experiencing some performance issues that this is going to address

@github-actions github-actions Bot added the Stale label Sep 22, 2024
@github-actions github-actions Bot closed this Sep 22, 2024
@codecov-commenter

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

Attention: Patch coverage is 90.00000% with 2 lines in your changes missing coverage. Please review.

Please upload report for BASE (master@fb3484e). Learn more about missing BASE report.
Report is 99 commits behind head on master.

Files with missing lines Patch % Lines
source/Grid/utils/CellSizeAndPositionManager.js 90.00% 2 Missing ⚠️

❗ Your organization needs to install the Codecov GitHub app to enable full functionality.

Additional details and impacted files
@@            Coverage Diff            @@
##             master    #1343   +/-   ##
=========================================
  Coverage          ?   90.35%           
=========================================
  Files             ?       59           
  Lines             ?     1752           
  Branches          ?        0           
=========================================
  Hits              ?     1583           
  Misses            ?      169           
  Partials          ?        0           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@bvaughn

bvaughn commented Oct 18, 2026

Copy link
Copy Markdown
Owner

Sorry for the very long delay in getting back to you about this!

I've just finished a large update for version 10 of react-virtualized (#1900): the library has been rewritten in TypeScript, every component is now a function component (React 18+ is required), and the source moved from source/ to lib/. Because of that, this PR can't be merged as-is. Version 10 still caches the size and position of every cell, even when the cell size is a fixed number.

If you're still interested in this change, I'd welcome a new PR with it rebased onto the version-10 branch (or onto master once version 10 has been merged).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.