bvaughn / react-virtualized

React components for efficiently rendering large lists and tabular data
http://bvaughn.github.io/react-virtualized/
MIT License
26.1k stars 3.05k forks source link

[STICKY] Tell me how you're using react-virtualized #147

Open bvaughn opened 8 years ago

bvaughn commented 8 years ago

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:

  1. What are you using react-virtualized for (eg. form controls, data grids, etc)?
  2. Which component(s) do you find most useful?
  3. (Optional) What product(s) / project(s) are you using react-virtualized in?
felipeleusin commented 8 years ago

HI,

First I would like to thank you for this project, it helped a lot when we had to work with some larger datasets.

  1. We're using virtualized for data grids and large tables.
  2. We had trouble using the built-in Editors, specially it would be good to export the EditorBase class so we can extend upon it. Also on mobile we noticed some performance degradation when using FlexTable (due to flexbox performance) so we instead switched to using a Grid with only one column and styling using regular float or inline-block. This was purely a perception (no idea how to benchmark this kind of thing) when testing in Android design and since it was an easy change in our use case.
bvaughn commented 8 years ago

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.

fermuch commented 8 years ago

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.

  1. Large lists of items. We have over 9000 items in a single list with different heights each, and using pagination was not an option.
  2. First I tried the InfiniteLoader. Using it was simple, and I really liked it, but most of the data was already on the client, so I VirtualScroll. I am surprised for how simple it is to set it up.

As of now, I don't really have anything to complain. The docs are clean and simple, the examples are short and concise.

bvaughn commented 8 years ago

Thanks for the kind words @fermuch. I'm glad to hear that you're finding the library easy to work with!

wmertens commented 8 years ago

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?

fermuch commented 8 years ago

@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;
                      }}
                      ...
wmertens commented 8 years ago

@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.

fermuch commented 8 years ago

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?

bvaughn commented 8 years ago

@fermuch, @wmertens: Let's move this discussion off of this GH issue. I opened this issue for a very specific reason. (I want to know how react-virtualized is being used.) Feature requests and trouble-shooting can be done one other, more focused issues (in this case maybe #149).

kasrak commented 8 years ago

Thanks for react-virtualized! We're using an internal fork of Grid for rendering a few different parts of the UI in Airtable. e.g. in embedded card lists, like this one: https://airtable.com/whatsnew

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:

 - getNumberOfItems()
 - getVisibleItemIndicesInRect(rect)
 - getContentSize(containerSize)
 - getComponentForItemAtIndex(itemIndex, containerSize)

If you want to chat about this more, feel free to email me at k@airtable.com!

andevsoftware commented 8 years ago

@kasrak I agree. I end up forking the Grid component too because I want more control over the way the items are rendered in the given visible boundaries. I think the delegate pattern is not too hard to implement looking at the way how the Grid component is set up atm. In my case I want to render items in a grid for example, see below. Would you mind giving an example of how the provider is set up?

chrome

andevsoftware commented 8 years ago

Perhaps https://developer.apple.com/library/ios/documentation/UIKit/Reference/UICollectionView_class/ can give more insight on this.

bvaughn commented 8 years ago

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. :)

bvaughn commented 8 years ago

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 Grid to make it a bit more customizable out of the box. If you're available sometime soon, maybe we could chat briefly as well so I could get a better sense of your use cases too.

bvaughn commented 8 years ago

FYI, I've filed issue #182 as well after a discussion with @kasrak. Goal is to support custom (non-checkerboard) layouts. Feedback welcome!

bvaughn commented 8 years ago

FYI @olivierandriessen release 6.1.0 supports a custom renderCellRanges property for Grid. Hope you're able to use it for your spreadsheet app.

nishp1 commented 8 years ago

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).

oyeanuj commented 8 years ago

Would like to really use it for a feed of stories with dynamic, non-predictable heights (similar to say that of Facebook) :)

bvaughn commented 8 years ago

@oyeanuj Let's chat about that on #149? :)

ifunk commented 8 years ago

We're using it to display thousands of thumbnail images in a grid. Works really well with Autosizer and Grid components... thanks!

cpinnix commented 8 years ago

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.

bvaughn commented 8 years ago

@cpinnix: Sounds like you could just use a debounced onSectionRendered callback for that?

cpinnix commented 8 years ago

@bvaughn Yeah. Right after posting I came up with a simple timeout solution.

const delay = 500;
let timeout = null;

...

_onScroll(data) {
  clearTimeout(timeout);
  timeout = setTimeout(() => {
    this.props.onScrollEnd(data.clientHeight, data.scrollHeight, data.scrollTop);
  }, delay);
}
MikeMcElroy commented 8 years ago

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).

bvaughn commented 8 years ago

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. :)

smitch88 commented 8 years ago

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.

https://github.com/cljsjs/packages/pull/544

I was using fixed-data-tables but I like your generic row buffering component VirtualScroll so I'm building a couple wrapper components around that and utilizing your FlexTable for some data grids.

My main Issues but not really blockers:

FlexTable

For the group headers, I have just wrapped a FlexTable with a container div + header div broken up as I need. I have no workaround for the fixed columns issue but it isnt a hard requirement for me at the moment.

clauderic commented 8 years ago

Hey there,

Thought I'd chime in since I've been using React Virtualized for a while now. I'd like to start off with a massive thank you. This project has truly been a godsend. In my experience, I've found it to perform a lot better than the other react virtual scrolling solutions out there 👍

I've been using the React Virtualized VirtualScroll component at work in a production to-do app built with Cordova and released for iOS and Android to render large lists of to-do's. I had to write my own sorting library, which came with it's own set of challenges, but the end-result is fantastic and the performance boost was massive. Gif doesn't really do it justice, but here's what it looks like (nevermind the dummy data 🙈)

sorting

We also opted for React Virtualized when the time came to revamp the date-picker in the app. We used it to create an infinite scrolling date-picker component, which we recently decided to open-source. I don't believe there is anything out there quite like it for React and we felt the community might benefit from it.

datepicker

In terms of improvements, are there any plans for supporting relative positioning for VirtualScroll elements? As well, I agree with @smitch88, Fixed headers would be a really nice feature, especially for mobile apps using RV

bvaughn commented 8 years ago

Fantastic, @clauderic! Thanks for sharing the videos. I love seeing what you've done with RV!

react-infinite-calendar in particular is slick! Just gave it a shout-out on Twitter. :)

The drag-and-drop UI is also very cool. Would love to see how you're implementing that. I get asked about that pretty regularly but up until this point, I haven't had to build it- so my recommendations are...vague. :D

clauderic commented 8 years ago

@bvaughn Thanks man, glad you appreciate it! And thanks for the shoutout! 😊

As for drag and drop... It was quite an interesting challenge to solve. Anytime elements come in and out of the DOM, you have to re-build the list of elements that will be animated as they get hovered over and keep track of their actual index in a data-attribute or something of the sort (as opposed to their index in the DOM). The logic is pretty straightforward on desktop, with translate3d animations and auto-scrolling. But on mobile it proved to be a lot more challenging, since touch events stop firing when the event.target element is removed from the dom (which inevitably happens when you start scrolling). Had to get pretty creative...

It's probably one of the next projects I'll work on open sourcing, but the code is pretty messy at the moment since it's tightly coupled with the app and is intertwined with pull to refresh and swipe actions.

bvaughn commented 8 years ago

If you do open-source it at some point, point me at it! I'd love to see it. :)

abhirathore2006 commented 8 years ago

@bvaughn i am using react-virtualized in a search page, however i have small issue actually more over a request, now it creates its own container, is it possible to make it use the same window scrollbar ... like this https://react.rocks/example/react-virtual-list because i have other content too and showing multiple scroll-bar doesn't look good

i believe this will make it a perfect solution.

SteveKennedy commented 8 years ago

@clauderic I know this is off topic, but can you point me to where I can find that to-do list manager? I can't find it on Android, and I've been looking to try new ones.

clauderic commented 8 years ago

@bvaughn Finally open-sourced the sortable higher-order component 🎉 It's still fairly experimental, but if you're looking for a dead-simple solution to add sortable functionality to your existing components or to a react-virtualized list, might be a decent option :) It also supports touch devices out of the box, and has a tiny footprint. https://github.com/clauderic/react-sortable-hoc

@SteveKennedy (It's called Nirvana)

confusingstraw commented 7 years ago

@bvaughn My favorite component is definitely a tie between AutoSizer and VirtualScroll. They give me a ton of flexibility in how I want to go about presenting the data. My latest use case was rendering very large trees of data. First I flatten the tree, building indexes by traversing the visible children, then VirtualScroll provides me an index and I simply render the node. It's been a huge lifesaver.

bvaughn commented 7 years ago

Thanks @rgfoley! That's great to hear. :)

I wish browsers native provided element resize events so that components like AutoSizer were unnecessary...

I'd love to see your tree implementation if it's somewhere that can be shared. I started a branch of react-virtualized that adds a Tree component (that sounds very similar to the one you're describing) but haven't had the time yet to finish it. :D

confusingstraw commented 7 years ago

@bvaughn Which branch has the component? (unless it's just local)

Mine is somewhat tied to the structure that I'm working with, specifically it is for a file tree structure with permissions and such tied to each directory, and isn't currently public.

The data provided to the component is an Immutable.js Map where each node knows the keys for it's parent and it's children, and every node is at the highest level (there is no nesting). From there it is mostly implementation specific things.

I'd love to look at what you've made so far!

kyle-ssg commented 7 years ago

Hey virtualizers,

Came across this project last week and have really enjoyed implementing with it. As well as being great for performance it demonstrates an excellent use of higher order components.

I've developed the following since, all of which would have been useful (and perhaps will be) in some of our previous projects.

bvaughn commented 7 years ago

@rgfoley Haven't pushed it yet. Need to tidy it up more before doing so. When I find the time, I'll share. :)

Cool stuff, @kyle-ssg! Thanks for sharing. Does your async-infinite-scroll build on top of RV or is it a separate thing? (If it builds on top, I'd be interested in seeing your implementation.) :)

oyeanuj commented 7 years ago

@kyle-ssg looks great! any plans to open source these components or PR it back here? :)

kyle-ssg commented 7 years ago

@bvaughn The infinite scroll is just its own component with a combination of AutoResizer, InfiniteLoader and logic around setting scroll top and reloading based on a threshold prop. One of the motivations behind this was also to get the propType names a bit closer to the react native list view.

@oyeanuj Potentially yes - these have been built as part of a work project so I'd have to ok it first 😄 . Would need to decouple bits from a custom Input component I built but that wouldn't take long. I think open sourcing would be the more sensible option as they are indeed separate components (albeit very lightweight thanks to what RV provides).

andrewmclagan commented 7 years ago

We are using react virtualised in a new buildout fro EthicalJobs.com.au

Rendering lists of organisations and jobs around 40,000 to 100,000 at a time.

so so so sweeeeet!

BTMPL commented 7 years ago
  1. I'm using react-virtualized in a data-grid displaying list of transaction made by the user
  2. FlexTable, FlexColumn, WindowScroller
  3. A PoC for banking institution

Only thing I'm missing over native implementation of rendering everything at one go is ability to search using Ctrl+F - I will have to implement that with a custom JS listener for the key combo and a override the browser implementation of search.

bvaughn commented 7 years ago

Thanks for the info @BTMPL!

You may want to check out my js-worker-search or redux-search libraries for the Ctrl+F filtering functionality. I use them in production in combination with react-virtualized and it works very smoothly.

andrewmclagan commented 7 years ago

We (EthicalJobs.com.au) are using it on our new build to display very large datasets within data-grid components. Performance was the main reason we migrated, although in the process we discovered allot to our likings. . . !

Thank you!

amilajack commented 7 years ago

I'm thinking of using it to display a list of around a hundred images. Does react-virtualized gc elements that are offscreen and have already been rendered?

bvaughn commented 7 years ago

@amilajack react-virtualized only caches elements temporarily while a user is scrolling. Otherwise they'll be GC'ed by the browser like normal. Others have used RV for a windowed gallery like you describe. :)

JobLeonard commented 7 years ago

We're building a data-browser for RNA data, where we have to quickly fetch and display data for a selection out of of 25000+ genes. The scrolling kinda breaks.. but we're basically using it more as a type-to-find input anyway:

WIP

A video shows off the use-case much better: https://youtu.be/l3FVAg1ZLH8

It's very much a WIP - as you can see the CSS is still very messed up (if you have any ideas what might be causing that please share, we're just naively importing the CSS + using react-bootstrap at the moment).

Above the react-select input you can actually see in the video how we did it before: a textarea where we had to type in the gene names, and then apply a regex afterwards... so yeah, big improvement there

bvaughn commented 7 years ago

Very cool @JobLeonard :)

The only thing I noticed messed up in the video was the placeholder text in react-select. (Is that what you meant?) Any chance you could point met at a demo? I'd be happy to take a look.

jayryemure commented 7 years ago

Hello, I'm using this great library in conjunction with React Select to create fancy drop downs with:

  1. Search term filtering
  2. Multiple selections
  3. Custom options rendering
  4. Dynamic option heights
  5. Up to 100000 options

My stack is:

<ReactSelect.Async>
   <AutoSizer>
      <VirtualScroll>

As far as 4, I tried using CellMeasurer but my task required being able to skip thousands of rows so I measured it by hand using HTML Canvas Context which is quite a bit faster but not nearly as solid and accurate as what CellMeasurer does.

(I'd love to post a screenshot here because it looks so good, but corporate regulations and such)

bvaughn commented 7 years ago

Hey @jayryemure,

Thanks for the info! 😁 No worries on the screenshot. I understand.

Wondering if you've seen the react-select-fast-filter-options library yet for filtering react-select options? If you have so many options you would likely see further performance benefits from using that library. 😄