-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
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
[STICKY] Tell me how you're using react-virtualized #147
Comments
HI, First I would like to thank you for this project, it helped a lot when we had to work with some larger datasets.
|
Thanks for being the first to reply @felipeleusin! Much appreciated. :) I also appreciate the note about flexbox performance on mobile. That's a good thing for me to potentially add to docs somewhere. |
I'd like to thank you for building such an awesome project. I've been using it since today, so my comment might not be as useful.
As of now, I don't really have anything to complain. The docs are clean and simple, the examples are short and concise. |
Thanks for the kind words @fermuch. I'm glad to hear that you're finding the library easy to work with! |
We're considering to use it for virtual scrolling through 200+ news items with variable height but right now we can't really use it because the API doesn't allow notifying of height changes after a row was rendered, or am I wrong? |
@wmertens the heights in my list are variable. I have it like this: <AutoSizer>
{({height, width}) => (
<VirtualScroll
width={width}
height={height}
rowsCount={markers.length}
rowHeight={(index) => {
const marker = markers[index];
if (selectedMarker === marker._id) {
return 225;
}
return 110;
}}
... |
@fermuch I would like to have variable-height-determined-by-browser rows, meaning that each row is laid out by the browser and that determines its rowHeight. With the current API that is not really possible I think, except by using something that forces a redraw of the VirtualScroll element after the correct row height is determined. |
Oh, I am not sure how to do that. You need to calculate how much rows are visible? Maybe an option to pass how many items are currently rendered would be a good idea? |
Thanks for react-virtualized! We're using an internal fork of We ended up forking because we needed more control over the actual DOM elements being emitted. Our component is only responsible for dynamic drawing and delegates the layout and rendering of individual items to a provider. Decoupling dynamic drawing from layout also makes it easy for us to reuse the component for arbitrary layouts in the future. The layout provider's interface is basically these 4 methods:
If you want to chat about this more, feel free to email me at [email protected]! |
@kasrak I agree. I end up forking the |
Perhaps https://developer.apple.com/library/ios/documentation/UIKit/Reference/UICollectionView_class/ can give more insight on this. |
FWIW I am interested in react-virtualized supporting the kind of flexible use-case described by @kasrak and @olivierandriessen. Let's work together to make that happen. :) |
FYI @kasrak - @olivierandriessen and I chatted on Hangout a bit ago and I created issue #181. The conversation gave me an idea for a small change or two that I could make to |
FYI @olivierandriessen release 6.1.0 supports a custom |
Brian, thanks for working on making the integration with react-select super easy! I am going to be using this library along with react-select to work on custom dropdowns with large datasets, nested expandable options, sectioned options (think optgroup). |
Would like to really use it for a feed of stories with dynamic, non-predictable heights (similar to say that of Facebook) :) |
We're using it to display thousands of thumbnail images in a grid. Works really well with Autosizer and Grid components... thanks! |
We're using VirtualScroll for large document images. One thing I'm looking for is the ability to know when scrolling has stopped to avoid loading large images in between a large scroll. Similar to FixedDataTable's onScrollEnd. Thinking about a solution now and open to solutions as well. |
@cpinnix: Sounds like you could just use a debounced |
@bvaughn Yeah. Right after posting I came up with a simple timeout solution.
|
We've settled on RV for our big React-based work project, and we've just settled on a series of patterns for our uses. We have chosen patterns for our tables, so a lot of options are unnecessarily verbose, and we didn't want to have to educate our devs on all of the features, so we decided to build a small DSL which simplifies about 75% of the usage of FlexTable/FlexColumn. Issues:
That said, I really like all the work that's been done on RV in the past, and am looking forward to seeing it improve (and helping where I can). |
Happy to hear that you've chosen to go with RV Mike! I think we can definitely improve a few of the points you've mentioned. Welcome onboard. :) |
I've been using RV in the clojurescript world and just added a PR into cljsjs package repo so it can be included as a dependency a bit easier for cljs builds. I was using fixed-data-tables but I like your generic row buffering component My main Issues but not really blockers: FlexTable
For the group headers, I have just wrapped a |
To be honest, after several variations (some using / managing my own CellMeasurerCache), where I ended up is almost embarrassingly simple. I sort of sole two ideas used by CellMeasuer (keyMapper and cache.rowHeight). Basically every row that comes in (via websocket) has a unique ID, so I calculate heights and store that info in a Map as they come in (and remove rolled ones). Then I feed the List a getRowHeight function that pulls directly from the Map via the rows ID (rather than index). And bumped up my max log size before rolling so that I wouldn't have to recomputeRowHeights() until people are being real gluttons. ;) So a little compromise, but seems to work well. |
Thanks for elaborating!
I'm mostly interested in how you do the calculations in a way that makes it faster than using |
Ahhh... I see. Well to be honest I'm not sure it would be any "quicker" mechanics-wise for lookups. (Map vs plucking from an object in the end?). I imagine CellMeasurer has some additional overhead in what it does calculating the heights, but in the end the reason I didn't use it wasn't directly related the performance of cached height lookups themselves. It was more about viewing performance when scrolling back (up). Basically lots of log rows can come in quickly (hundreds a second at times) and it's trivial for me to compute their height as they come in so I always have a complete cache of all that info before any element is rendered in the list. So scrolling back up is always smooth, no jerkyness due to calculations of height data not in the cache yet (which would come going the CellMeasurer route in my case) The only real hitch for me at this point is once the log starts to roll (at 100k entries currently) where recomputeRowHeights() has to hit, potentially quite frequently as new data pours in. There are things I can do about that (delaying the recalc until they decide to scroll up again, or maybe the flow has slowed or stopped a cycle). But beyond that for my use case RV would need to have more control over and understanding of the manipulation of the list/grid data. Like telling it index 0-121 are gone now and it having an optimal way of just removing that range and recalculating, etc. I can't say I looked deep enough to understand or know what's going on completely, but it seemed like that would be a somewhat difficult given they way the internal caches are currently (object props based on index numbers IIRC). Sorry if I'm not clear here. But basically just saying it would need to be able to better "understand" list modifications for my use case rather then a full recomputeRowHeights() with 10 new rows rolling through. (even though cached heights are at least used) The next step would just for that recompute to be minimized to only what's changed. But in order to do that it would have to have an understanding of the change and the underlying caches would have to be in some form that make manipulation like that possible/performant. Wow.. that's some rambling. Time to cut myself off ;) EDIT: Actually and now that I think about how row height have to be formulated and summed, it may not even be possible (or worthwhile) ! It's a tough problem for sure. |
Ah, yes. Sounds like we're both using objects for our "maps". I wouldn't imagine much of a perf difference there. I was more asking about the process of measuring/calculating initially.
Hm! This should be the case for
Based on the index by default, but can be based on a more stable id if you provide the cache a
I may be misunderstanding you, but this is part of why the measurements ( All that being said, I believe that you found a way to improve perf in your app. I'd love to better understand how you did it though, in case anything could be applied to the built-in react-virtualized components. 😄 Don't suppose you could show me your code? |
So the application I've been working on is finally opened to the public: https://github.com/linnarsson-lab/loom-viewer I probably should start adding some gifs... To quote my comment from last year:
Funny enough, the scrolling (with the mouse) is currently broken too, but in this case it's a known issue with React-Select, not me ;) |
Yep, that part is true, but isn't really the snag I ran into using it. :) The key to what I was trying to avoid with it is actually mentioned -- "once the item has been measured". Basically at times my new log data can come in so quickly that many items are not rendered as they come in, and therefore are not measured (and height cached) by CellMeasurer as they come in. For example, my list view may show 10-30 items at a time (depending on heights), and is usually pinned to the "end" of the list via The end effect of going that deferred measurement route, with chunks of missing heights in the CellMeasurer cache, was jerky upward scroll movement, as CellMeasurer would actually measure and cache heights that it didn't have a chance to previously. Basically it's what some people are trying to find a general solution for in #803 and #610. Since I had an easy calculation I could run to generate and cache row heights for each item, as they came in, before each render, that just seemed to be the cleanest route. At first I did try using
Yes.. and that's a concept I stole from CellMeasurer for my cache and measure functions also. Definitely needed in my case. I think where I probably confused you is talking about several caches without being specific. Both CellMeasurerCache's height cache (when used with a keyMapper) and my simple height cache serve the same function -- caching raw height info for each row via some id. I just cached things manually so I was assured there was complete height cache, with entry for every row as mentioned above. I doubt there is much (if any) performance benefit beyond working around that scrolling quirk. If there was any, it would just be from reduced code for a height "measurement" as mine is trivial. But then there are the other "higher level" internal caches for the list (
Prepare for disappointment!! ;) The relevant parts are really trivial... Basically I get new rows via via websocket in a parent container component. As they come in, I just call the appropriate method to calculate and cache height which are like: // Set our calculated height for a PostAuth log row
setPostAuthRowHeight(row) {
this.rowHeightCache.set(row.id, (20 + 20 * row.payload.extraRows));
} ...and of course delete id's from that rowHeighCache Map once they are pushed out of the log. So I always have fully populated cache for the log(s) based on ID. Then for my list: <List
style={{outline: 'none' }}
width={width}
height={height}
rowCount={p.log.length}
noRowsRenderer={this.noRowsRenderer.bind(this)}
rowRenderer={this.rowRenderer.bind(this)}
onScroll={this.logScrolled.bind(this)}
scrollToIndex= {p.syncLog ? p.log.length -1 : undefined }
rowHeight={this.getRowHeight.bind(this)}
ref={p.sendListElement}
/> Which gets the heights via // Return our calculated hight for a log row
getRowHeight({index}) {
return this.props.getRowHeight(this.props.log[index].id);
} Which just uses the getRowHeight function prop that's passed in: // Get our calculated height for a log row (sent as prop to WebConsole)
getRowHeight(id) {
return this.rowHeightCache.get(id);
} I'm sure you get the idea. Its just a raw Map being used. Sorry to give you any false hope. :) Although now that I think about it, I may just try sending the calculated row hight in as part of the actual log entry. That should be about as direct as possible! Sorry to get wordy, thanks again. |
I put together a little slider/carousel with react-virtualized and react-motion. Feedback/PRs welcome! 🙂 https://github.com/treyhoover/react-sliderp |
Hi! We builds filemanager for react using react-virtualized. https://github.com/OpusCapita/filemanager Now we use |
Cool! Thanks for sharing, @kvolkovich-sc 😁 |
Hi there! Is anyone using react-virtualized with the cellMeasurer to renderer a List having truely dynamic row heights they can share? I mean row content is variable which is of unknown height and cannot be provided to the RV component. I see references to doing this in other issues but not seeing it actually being done in any examples. From what I can see the height is always provided in the examples. I am building a chat client which each message has content of variable height. I assume this is what the cellMeasurer is built for. In my case my measurerCache gets updated according to row content height so the measurer seems to be doing its job but the Grid ref is always undefined. /Grid.js Any examples of someone actually having RV calculate the height of the content would be a great help! |
Hi @ryanflowers. This issue isn't for Q&A. 😄 That's better suited for Slack and Stack Overflow. There's an example of what you're asking about on the react-virtualized demo page and the source is in this repo as well. If you have follow-up questions about this, please hop in the Slack and ask them there. 👍 |
I am using this for a Cordova app I am building which lists out about 700+ objects in the form of component links that are pretty complex, lots of even handlers and dynamic data. I came across it while searching for a solution because when the whole list is rendered, the animations and transitions on the page broke down quite a bit and became unusable. That being said, WindowScroller and VirtualScroll are the only components I have used so far. Its been great! The app itself is basically a creature repository for D&D that is filterable/searchable, but there is a LOT of data processing, and react-virtualized has made my performance skyrocket. Really the only issue I've come across is making a mobile 1 column grid responsive to become a 2 column grid on larger screen sizes. |
I've created a partial https://github.com/cquiroz/scalajs-react-virtualized We use it on a realtime monitoring software on the Gemini Observatory where our primary language is scala and use scala.js for the front end Thanks this project has been invaluable to make our UI much more usable |
gw2efficiency for the virtualized tables (these are all the skins in the game Guild Wars 2, ordered by how many uses of the page have unlocked them and their unlock value). Also, multiple internal projects (that I can sadly not share) use the select menus. |
@Codelica great interface! BTW how do you deal with window resize? Do you recalculate all rows height? |
@MarcMagnin Thx. Mobile (phone) support wasn't a concern for this one, so there is a reasonable min-width set to keep log lines from wrapping, and a fixed hight is set for the console view. But yes, changes like that would require a re-calc/render. I used React Material UI on that (https://material-ui-next.com/) so the main layout font is Roboto. Console view uses Source Code Pro. |
Using it in a mobile cordova app for chat. |
Great work @bvaughn...thank you so much for your contribution... Here is my Reference implementation, List of popular movies from tmpb (over 18000 of them). Used flex-box, material-ui to display as cards. Demo
|
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
Thanks for all the great work you've done on this project! We use it for all of our grids on www.skipcard.com |
This comment has been minimized.
This comment has been minimized.
Hi there. Firstly this library had been hugely useful to me so thanks for taking the time to save a lot of mine. I have a simple question however I recently tried a simple implementation of the virtualized list component with a specified height and width in addition to using the the CellMeasurer component to calculate the heights of my rows dynamically. I have found that while varied div sizes are easily responding to these height discrepancies when I use the input form element with multiline functionality the height of the containing element is used as if no text were expanding the cell and I was wondering if there is any way to account for the size changes of the input. I am not certain how the CellMeasurer acquires its calculated heights but I'm slightly confused that the measurement of the JSX elements prior to the entry of the state into the input is used when I have seen through a ref on the top level element that the size seems to have been accounted for on the first render within the JSX. Any help would be appreciated. |
This is a stable library that we are using for a while, I am wondering if it supports web components as part of the row, especially with cellMeasurer in rowrenderer? |
A better understanding of how react-virtualized is being used will help me better prioritize features and shape the roadmap going forward. So if you're using this project, I'd love for you to leave a comment and tell me the following:
The text was updated successfully, but these errors were encountered: