Adding reselect and working through selectors - massive render performance improvement

This commit is contained in:
James Barnsley
2020-09-22 06:59:15 +12:00
parent 9a3b9cb1bf
commit ae83352dfb
14 changed files with 425 additions and 309 deletions

View File

@ -15,12 +15,13 @@ import * as mopidyActions from '../../services/mopidy/actions';
import * as googleActions from '../../services/google/actions';
import * as spotifyActions from '../../services/spotify/actions';
import { sortItems, applyFilter } from '../../util/arrays';
import { collate } from '../../util/format';
import Button from '../../components/Button';
import { i18n, I18n } from '../../locale';
import { isLoading } from '../../util/helpers';
import Loader from '../../components/Loader';
import { getLibraryItems } from '../../util/selectors';
import {
makeLibrarySelector,
makeLoadingSelector,
} from '../../util/selectors';
class LibraryAlbums extends React.Component {
constructor(props) {
@ -207,7 +208,7 @@ class LibraryAlbums extends React.Component {
sort,
sort_reverse,
view,
load_queue,
loading,
} = this.props;
const {
limit,
@ -215,7 +216,7 @@ class LibraryAlbums extends React.Component {
} = this.state;
let { albums } = this.props;
if (isLoading(load_queue, ['(.*):library:albums'])) {
if (loading) {
return <Loader body loading />;
}
@ -281,8 +282,6 @@ class LibraryAlbums extends React.Component {
per_page,
} = this.state;
console.log('RENDER')
const source_options = [
{
value: 'all',
@ -403,16 +402,20 @@ class LibraryAlbums extends React.Component {
const mapStateToProps = (state) => {
const source = state.ui.library_albums_source ? state.ui.library_albums_source : 'all';
const loadingSelector = makeLoadingSelector(['(.*):library:albums']);
const spotifyLibrarySelector = makeLibrarySelector('spotify:library:albums');
const googleLibrarySelector = makeLibrarySelector('google:library:albums');
const mopidyLibrarySelector = makeLibrarySelector('mopidy:library:albums');
const albums = [
...(source === 'all' || source === 'spotify' ? getLibraryItems(state, 'spotify:library:albums') : []),
...(source === 'all' || source === 'google' ? getLibraryItems(state, 'google:library:albums') : []),
...(source === 'all' || source === 'local' ? getLibraryItems(state, 'mopidy:library:albums') : []),
...(source === 'all' || source === 'spotify' ? spotifyLibrarySelector(state) : []),
...(source === 'all' || source === 'google' ? googleLibrarySelector(state) : []),
...(source === 'all' || source === 'local' ? mopidyLibrarySelector(state) : []),
];
return {
mopidy_uri_schemes: state.mopidy.uri_schemes,
load_queue: state.ui.load_queue,
loading: loadingSelector(state),
albums,
google_available: (state.mopidy.uri_schemes && state.mopidy.uri_schemes.includes('gmusic:')),
spotify_available: state.spotify.access_token,

View File

@ -19,6 +19,10 @@ import { I18n, i18n } from '../../locale';
import { collate, collateLibrary } from '../../util/format';
import Button from '../../components/Button';
import Loader from '../../components/Loader';
import {
makeLibrarySelector,
makeLoadingSelector,
} from '../../util/selectors';
class LibraryArtists extends React.Component {
constructor(props) {
@ -148,31 +152,21 @@ class LibraryArtists extends React.Component {
renderView = () => {
const {
spotify_library,
google_library,
mopidy_library,
items,
source,
sort,
sort_reverse,
view,
load_queue,
loading,
} = this.props;
const {
limit,
filter,
} = this.state;
let { artists } = this.props;
if (isLoading(load_queue, ['(.*):library:artists'])) {
if (loading) {
return <Loader body loading />;
}
let artists = [
...(source === 'all' || source === 'spotify' ? collate(spotify_library, { items }).items : []),
...(source === 'all' || source === 'google' ? collate(google_library, { items }).items : []),
...(source === 'all' || source === 'local' ? collate(mopidy_library, { items }).items : []),
];
if (sort) {
artists = sortItems(artists, sort, sort_reverse);
}
@ -336,20 +330,37 @@ class LibraryArtists extends React.Component {
}
}
const mapStateToProps = (state) => ({
mopidy_uri_schemes: state.mopidy.uri_schemes,
google_available: (state.mopidy.uri_schemes && state.mopidy.uri_schemes.includes('gmusic:')),
spotify_available: state.spotify.access_token,
items: state.core.items,
mopidy_library: state.core.libraries['mopidy:library:artists'] || { items_uris: [] },
spotify_library: state.core.libraries['spotify:library:artists'] || { items_uris: [] },
google_library: state.core.libraries['google:library:artists'] || { items_uris: [] },
source: (state.ui.library_artists_source ? state.ui.library_artists_source : 'all'),
sort: (state.ui.library_artists_sort ? state.ui.library_artists_sort : null),
sort_reverse: (state.ui.library_artists_sort_reverse ? state.ui.library_artists_sort_reverse : false),
view: state.ui.library_artists_view,
load_queue: state.ui.load_queue,
});
const mapStateToProps = (state) => {
const source = state.ui.library_albums_source ? state.ui.library_albums_source : 'all';
const loadingSelector = makeLoadingSelector(['(.*):library:artists']);
const spotifyLibrarySelector = makeLibrarySelector('spotify:library:artists');
const googleLibrarySelector = makeLibrarySelector('google:library:artists');
const mopidyLibrarySelector = makeLibrarySelector('mopidy:library:artists');
const artists = [
...(source === 'all' || source === 'spotify' ? spotifyLibrarySelector(state) : []),
...(source === 'all' || source === 'google' ? googleLibrarySelector(state) : []),
...(source === 'all' || source === 'local' ? mopidyLibrarySelector(state) : []),
];
/**
TODO
Apply sort, filter and source rules to the selector.
This will mean we have a universal selector for all libraries. WIN!
**/
return {
mopidy_uri_schemes: state.mopidy.uri_schemes,
google_available: (state.mopidy.uri_schemes && state.mopidy.uri_schemes.includes('gmusic:')),
spotify_available: (state.spotify.access_token),
artists,
loading: loadingSelector(state),
source,
sort: (state.ui.library_artists_sort ? state.ui.library_artists_sort : null),
sort_reverse: (state.ui.library_artists_sort_reverse ? state.ui.library_artists_sort_reverse : false),
view: state.ui.library_artists_view,
};
};
const mapDispatchToProps = (dispatch) => ({
uiActions: bindActionCreators(uiActions, dispatch),