1
0
mirror of https://github.com/Sonarr/Sonarr.git synced 2026-04-22 22:16:13 -04:00

New: Improved Series list performance

This commit is contained in:
ta264
2020-01-05 21:49:08 +00:00
committed by Mark McDowall
parent 466d4fba9e
commit 5a79b8502e
14 changed files with 257 additions and 418 deletions
@@ -1,12 +1,9 @@
import _ from 'lodash';
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import { Grid, WindowScroller } from 'react-virtualized';
import getIndexOfFirstCharacter from 'Utilities/Array/getIndexOfFirstCharacter';
import hasDifferentItemsOrOrder from 'Utilities/Object/hasDifferentItemsOrOrder';
import dimensions from 'Styles/Variables/dimensions';
import { sortDirections } from 'Helpers/Props';
import Measure from 'Components/Measure';
import SeriesIndexItemConnector from 'Series/Index/SeriesIndexItemConnector';
import SeriesIndexOverview from './SeriesIndexOverview';
@@ -66,56 +63,44 @@ class SeriesIndexOverviews extends Component {
rowHeight: calculateRowHeight(238, null, props.isSmallScreen, {})
};
this._isInitialized = false;
this._grid = null;
}
componentDidMount() {
this._contentBodyNode = ReactDOM.findDOMNode(this.props.contentBody);
}
componentDidUpdate(prevProps) {
componentDidUpdate(prevProps, prevState) {
const {
items,
filters,
sortKey,
sortDirection,
overviewOptions,
jumpToCharacter
} = this.props;
const itemsChanged = hasDifferentItemsOrOrder(prevProps.items, items);
const overviewOptionsChanged = !_.isMatch(prevProps.overviewOptions, overviewOptions);
const {
width,
rowHeight
} = this.state;
if (
prevProps.sortKey !== sortKey ||
prevProps.overviewOptions !== overviewOptions ||
itemsChanged
) {
if (prevProps.sortKey !== sortKey ||
prevProps.overviewOptions !== overviewOptions) {
this.calculateGrid();
}
if (
prevProps.filters !== filters ||
prevProps.sortKey !== sortKey ||
prevProps.sortDirection !== sortDirection ||
itemsChanged ||
overviewOptionsChanged
) {
if (this._grid &&
(prevState.width !== width ||
prevState.rowHeight !== rowHeight ||
hasDifferentItemsOrOrder(prevProps.items, items))) {
// recomputeGridSize also forces Grid to discard its cache of rendered cells
this._grid.recomputeGridSize();
}
if (jumpToCharacter != null && jumpToCharacter !== prevProps.jumpToCharacter) {
const index = getIndexOfFirstCharacter(items, jumpToCharacter);
if (index != null) {
const {
rowHeight
} = this.state;
if (this._grid && index != null) {
const scrollTop = rowHeight * index;
this.props.onScroll({ scrollTop });
this._grid.scrollToCell({
rowIndex: index,
columnIndex: 0
});
}
}
}
@@ -123,21 +108,6 @@ class SeriesIndexOverviews extends Component {
//
// Control
scrollToFirstCharacter(character) {
const items = this.props.items;
const {
rowHeight
} = this.state;
const index = getIndexOfFirstCharacter(items, character);
if (index != null) {
const scrollTop = rowHeight * index;
this.props.onScroll({ scrollTop });
}
}
setGridRef = (ref) => {
this._grid = ref;
}
@@ -219,22 +189,14 @@ class SeriesIndexOverviews extends Component {
this.calculateGrid(width, this.props.isSmallScreen);
}
onSectionRendered = () => {
if (!this._isInitialized && this._contentBodyNode) {
this.props.onRender();
this._isInitialized = true;
}
}
//
// Render
render() {
const {
scroller,
items,
scrollTop,
isSmallScreen,
onScroll
isSmallScreen
} = this.props;
const {
@@ -243,29 +205,38 @@ class SeriesIndexOverviews extends Component {
} = this.state;
return (
<Measure onMeasure={this.onMeasure}>
<Measure
whitelist={['width']}
onMeasure={this.onMeasure}
>
<WindowScroller
scrollElement={isSmallScreen ? undefined : this._contentBodyNode}
onScroll={onScroll}
scrollElement={isSmallScreen ? undefined : scroller}
>
{({ height, isScrolling }) => {
{({ height, registerChild, onChildScroll, scrollTop }) => {
if (!height) {
return <div />;
}
return (
<Grid
ref={this.setGridRef}
className={styles.grid}
autoHeight={true}
height={height}
columnCount={1}
columnWidth={width}
rowCount={items.length}
rowHeight={rowHeight}
width={width}
scrollTop={scrollTop}
overscanRowCount={2}
cellRenderer={this.cellRenderer}
onSectionRendered={this.onSectionRendered}
isScrollingOptOut={true}
/>
<div ref={registerChild}>
<Grid
ref={this.setGridRef}
className={styles.grid}
autoHeight={true}
height={height}
columnCount={1}
columnWidth={width}
rowCount={items.length}
rowHeight={rowHeight}
width={width}
onScroll={onChildScroll}
scrollTop={scrollTop}
overscanRowCount={2}
cellRenderer={this.cellRenderer}
scrollToAlignment={'start'}
isScrollingOptOut={true}
/>
</div>
);
}
}
@@ -277,20 +248,15 @@ class SeriesIndexOverviews extends Component {
SeriesIndexOverviews.propTypes = {
items: PropTypes.arrayOf(PropTypes.object).isRequired,
filters: PropTypes.arrayOf(PropTypes.object).isRequired,
sortKey: PropTypes.string,
sortDirection: PropTypes.oneOf(sortDirections.all),
overviewOptions: PropTypes.object.isRequired,
scrollTop: PropTypes.number.isRequired,
jumpToCharacter: PropTypes.string,
contentBody: PropTypes.object.isRequired,
scroller: PropTypes.instanceOf(Element).isRequired,
showRelativeDates: PropTypes.bool.isRequired,
shortDateFormat: PropTypes.string.isRequired,
longDateFormat: PropTypes.string.isRequired,
isSmallScreen: PropTypes.bool.isRequired,
timeFormat: PropTypes.string.isRequired,
onRender: PropTypes.func.isRequired,
onScroll: PropTypes.func.isRequired
timeFormat: PropTypes.string.isRequired
};
export default SeriesIndexOverviews;