I have almost the same problem as Facebook has when rendering it's feed. As soon as a lot of posts are rendered, performance problems appear. After some research I found react-virtualized, which is awesome but I am having trouble to make it work for my app.
These are the problems that I am facing:
- Since each post can have an iframe embedded, or an image, I am firing the
measure
callback from theCellMeasurer
once these items are loaded. Because of this, some items seem misaligned. I tried doingparent.measureAllRows()
andparent.recomputeRowHeights()
each time themeasure
callback is called to see if it would fix it but it doesn't. - Each post has an expandable section, therefore I need to recalculate it's height. Is there any alternative aside from sending the props to the component?
This is the setup:
class VirtualPostList extends React.PureComponent {
constructor(props, context) {
super(props, context);
this._cache = new ReactVirtualized.CellMeasurerCache({
fixedWidth: true,
defaultHeight: 400
});
this.rowRenderer = this.rowRenderer.bind(this);
}
rowRenderer({index, isScrolling, key, parent, style}) {
return (
<ReactVirtualized.CellMeasurer
cache={this._cache}
columnIndex={0}
key={key}
parent={parent}
rowIndex={index}>
{({measure}) => (
<div key={key} style={style}>
<Post onLoad={measure}/>
</div>
)}
</ReactVirtualized.CellMeasurer>
)
}
componentDidUpdate(){
this.listComponent.recomputeRowHeights();
}
render() {
const cache = this._cache;
const rowCount = this.props.posts.length;
const _this = this;
return (
<ReactVirtualized.WindowScroller>
{({height, isScrolling, onChildScroll, scrollTop}) =>
<ReactVirtualized.AutoSizer disableHeight>
{({width}) =>
<ReactVirtualized.List
autoHeight
isScrolling={isScrolling}
height={height}
width={width}
rowCount={rowCount}
deferredMeasurementCache={cache}
rowHeight={cache.rowHeight}
rowRenderer={this.rowRenderer}
scrollTop={scrollTop}
onScroll={onChildScroll}
ref={(listComponent) => _this.listComponent = listComponent}
/>
}
</ReactVirtualized.AutoSizer>}
</ReactVirtualized.WindowScroller>
)
}
}
Example of overlap: