Improve series index performance during series refresh

This commit is contained in:
Mark McDowall 2019-04-06 22:59:27 -07:00
parent b40d7d89a1
commit 82b35f095e
10 changed files with 111 additions and 18 deletions

View File

@ -22,7 +22,7 @@ import SeriesIndexOverviewsConnector from './Overview/SeriesIndexOverviewsConnec
import SeriesIndexFilterMenu from './Menus/SeriesIndexFilterMenu'; import SeriesIndexFilterMenu from './Menus/SeriesIndexFilterMenu';
import SeriesIndexSortMenu from './Menus/SeriesIndexSortMenu'; import SeriesIndexSortMenu from './Menus/SeriesIndexSortMenu';
import SeriesIndexViewMenu from './Menus/SeriesIndexViewMenu'; import SeriesIndexViewMenu from './Menus/SeriesIndexViewMenu';
import SeriesIndexFooter from './SeriesIndexFooter'; import SeriesIndexFooterConnector from './SeriesIndexFooterConnector';
import styles from './SeriesIndex.css'; import styles from './SeriesIndex.css';
function getViewComponent(view) { function getViewComponent(view) {
@ -330,9 +330,7 @@ class SeriesIndex extends Component {
{...otherProps} {...otherProps}
/> />
<SeriesIndexFooter <SeriesIndexFooterConnector />
series={items}
/>
</div> </div>
} }

View File

@ -2,7 +2,7 @@ import PropTypes from 'prop-types';
import React, { Component } from 'react'; import React, { Component } from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
import createClientSideCollectionSelector from 'Store/Selectors/createClientSideCollectionSelector'; import createSeriesClientSideCollectionItemsSelector from 'Store/Selectors/createSeriesClientSideCollectionItemsSelector';
import dimensions from 'Styles/Variables/dimensions'; import dimensions from 'Styles/Variables/dimensions';
import createCommandExecutingSelector from 'Store/Selectors/createCommandExecutingSelector'; import createCommandExecutingSelector from 'Store/Selectors/createCommandExecutingSelector';
import createDimensionsSelector from 'Store/Selectors/createDimensionsSelector'; import createDimensionsSelector from 'Store/Selectors/createDimensionsSelector';
@ -39,7 +39,7 @@ function getScrollTop(view, scrollTop, isSmallScreen) {
function createMapStateToProps() { function createMapStateToProps() {
return createSelector( return createSelector(
createClientSideCollectionSelector('series', 'seriesIndex'), createSeriesClientSideCollectionItemsSelector('seriesIndex'),
createCommandExecutingSelector(commandNames.REFRESH_SERIES), createCommandExecutingSelector(commandNames.REFRESH_SERIES),
createCommandExecutingSelector(commandNames.RSS_SYNC), createCommandExecutingSelector(commandNames.RSS_SYNC),
createDimensionsSelector(), createDimensionsSelector(),

View File

@ -0,0 +1,16 @@
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import SeriesIndexFooter from './SeriesIndexFooter';
function createMapStateToProps() {
return createSelector(
(state) => state.series.items,
(series) => {
return {
series
};
}
);
}
export default connect(createMapStateToProps)(SeriesIndexFooter);

View File

@ -5,8 +5,8 @@ import { connect } from 'react-redux';
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
import createSeriesSelector from 'Store/Selectors/createSeriesSelector'; import createSeriesSelector from 'Store/Selectors/createSeriesSelector';
import createExecutingCommandsSelector from 'Store/Selectors/createCommandsSelector'; import createExecutingCommandsSelector from 'Store/Selectors/createCommandsSelector';
import createQualityProfileSelector from 'Store/Selectors/createQualityProfileSelector'; import createSeriesQualityProfileSelector from 'Store/Selectors/createSeriesQualityProfileSelector';
import createLanguageProfileSelector from 'Store/Selectors/createLanguageProfileSelector'; import createSeriesLanguageProfileSelector from 'Store/Selectors/createSeriesLanguageProfileSelector';
import { executeCommand } from 'Store/Actions/commandActions'; import { executeCommand } from 'Store/Actions/commandActions';
import * as commandNames from 'Commands/commandNames'; import * as commandNames from 'Commands/commandNames';
@ -31,8 +31,8 @@ function selectShowSearchAction() {
function createMapStateToProps() { function createMapStateToProps() {
return createSelector( return createSelector(
createSeriesSelector(), createSeriesSelector(),
createQualityProfileSelector(), createSeriesQualityProfileSelector(),
createLanguageProfileSelector(), createSeriesLanguageProfileSelector(),
selectShowSearchAction(), selectShowSearchAction(),
createExecutingCommandsSelector(), createExecutingCommandsSelector(),
( (
@ -82,7 +82,7 @@ function createMapStateToProps() {
} }
const mapDispatchToProps = { const mapDispatchToProps = {
executeCommand dispatchExecuteCommand: executeCommand
}; };
class SeriesIndexItemConnector extends Component { class SeriesIndexItemConnector extends Component {
@ -91,14 +91,14 @@ class SeriesIndexItemConnector extends Component {
// Listeners // Listeners
onRefreshSeriesPress = () => { onRefreshSeriesPress = () => {
this.props.executeCommand({ this.props.dispatchExecuteCommand({
name: commandNames.REFRESH_SERIES, name: commandNames.REFRESH_SERIES,
seriesId: this.props.id seriesId: this.props.id
}); });
} }
onSearchPress = () => { onSearchPress = () => {
this.props.executeCommand({ this.props.dispatchExecuteCommand({
name: commandNames.SERIES_SEARCH, name: commandNames.SERIES_SEARCH,
seriesId: this.props.id seriesId: this.props.id
}); });
@ -132,7 +132,7 @@ class SeriesIndexItemConnector extends Component {
SeriesIndexItemConnector.propTypes = { SeriesIndexItemConnector.propTypes = {
id: PropTypes.number, id: PropTypes.number,
component: PropTypes.func.isRequired, component: PropTypes.func.isRequired,
executeCommand: PropTypes.func.isRequired dispatchExecuteCommand: PropTypes.func.isRequired
}; };
export default connect(createMapStateToProps, mapDispatchToProps)(SeriesIndexItemConnector); export default connect(createMapStateToProps, mapDispatchToProps)(SeriesIndexItemConnector);

View File

@ -0,0 +1,9 @@
import { createSelectorCreator, defaultMemoize } from 'reselect';
import _ from 'lodash';
const createDeepEqualSelector = createSelectorCreator(
defaultMemoize,
_.isEqual
);
export default createDeepEqualSelector;

View File

@ -1,4 +1,3 @@
import _ from 'lodash';
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
function createLanguageProfileSelector() { function createLanguageProfileSelector() {
@ -6,7 +5,9 @@ function createLanguageProfileSelector() {
(state, { languageProfileId }) => languageProfileId, (state, { languageProfileId }) => languageProfileId,
(state) => state.settings.languageProfiles.items, (state) => state.settings.languageProfiles.items,
(languageProfileId, languageProfiles) => { (languageProfileId, languageProfiles) => {
return _.find(languageProfiles, { id: languageProfileId }); return languageProfiles.find((profile) => {
return profile.id === languageProfileId;
});
} }
); );
} }

View File

@ -1,4 +1,3 @@
import _ from 'lodash';
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
function createQualityProfileSelector() { function createQualityProfileSelector() {
@ -6,7 +5,9 @@ function createQualityProfileSelector() {
(state, { qualityProfileId }) => qualityProfileId, (state, { qualityProfileId }) => qualityProfileId,
(state) => state.settings.qualityProfiles.items, (state) => state.settings.qualityProfiles.items,
(qualityProfileId, qualityProfiles) => { (qualityProfileId, qualityProfiles) => {
return _.find(qualityProfiles, { id: qualityProfileId }); return qualityProfiles.find((profile) => {
return profile.id === qualityProfileId;
});
} }
); );
} }

View File

@ -0,0 +1,36 @@
import { createSelector } from 'reselect';
import createDeepEqualSelector from './createDeepEqualSelector';
import createClientSideCollectionSelector from './createClientSideCollectionSelector';
function createUnoptimizedSelector(uiSection) {
return createSelector(
createClientSideCollectionSelector('series', uiSection),
(series) => {
const items = series.items.map((s) => {
const {
id,
sortTitle
} = s;
return {
id,
sortTitle
};
});
return {
...series,
items
};
}
);
}
function createSeriesClientSideCollectionItemsSelector(uiSection) {
return createDeepEqualSelector(
createUnoptimizedSelector(uiSection),
(series) => series
);
}
export default createSeriesClientSideCollectionItemsSelector;

View File

@ -0,0 +1,16 @@
import { createSelector } from 'reselect';
import createSeriesSelector from './createSeriesSelector';
function createSeriesLanguageProfileSelector() {
return createSelector(
(state) => state.settings.languageProfiles.items,
createSeriesSelector(),
(languageProfiles, series) => {
return languageProfiles.find((profile) => {
return profile.id === series.languageProfileId;
});
}
);
}
export default createSeriesLanguageProfileSelector;

View File

@ -0,0 +1,16 @@
import { createSelector } from 'reselect';
import createSeriesSelector from './createSeriesSelector';
function createSeriesQualityProfileSelector() {
return createSelector(
(state) => state.settings.qualityProfiles.items,
createSeriesSelector(),
(qualityProfiles, series) => {
return qualityProfiles.find((profile) => {
return profile.id === series.qualityProfileId;
});
}
);
}
export default createSeriesQualityProfileSelector;