From dd8d1b673e0d1b31cf88c7e6bd9150a166f3d1d3 Mon Sep 17 00:00:00 2001 From: ta264 Date: Sun, 5 Jan 2020 21:17:21 +0000 Subject: [PATCH] Faster hasDifferentItems and specialized OrOrder version --- .../Index/Overview/SeriesIndexOverviews.js | 4 ++-- .../Index/Posters/SeriesIndexPosters.js | 4 ++-- frontend/src/Series/Index/SeriesIndex.js | 9 ++++---- .../src/Utilities/Object/hasDifferentItems.js | 19 ++++++++++++----- .../Object/hasDifferentItemsOrOrder.js | 21 +++++++++++++++++++ 5 files changed, 43 insertions(+), 14 deletions(-) create mode 100644 frontend/src/Utilities/Object/hasDifferentItemsOrOrder.js diff --git a/frontend/src/Series/Index/Overview/SeriesIndexOverviews.js b/frontend/src/Series/Index/Overview/SeriesIndexOverviews.js index 3d0ab8c20..5202c5b1c 100644 --- a/frontend/src/Series/Index/Overview/SeriesIndexOverviews.js +++ b/frontend/src/Series/Index/Overview/SeriesIndexOverviews.js @@ -4,7 +4,7 @@ import React, { Component } from 'react'; import ReactDOM from 'react-dom'; import { Grid, WindowScroller } from 'react-virtualized'; import getIndexOfFirstCharacter from 'Utilities/Array/getIndexOfFirstCharacter'; -import hasDifferentItems from 'Utilities/Object/hasDifferentItems'; +import hasDifferentItemsOrOrder from 'Utilities/Object/hasDifferentItemsOrOrder'; import dimensions from 'Styles/Variables/dimensions'; import { sortDirections } from 'Helpers/Props'; import Measure from 'Components/Measure'; @@ -84,7 +84,7 @@ class SeriesIndexOverviews extends Component { jumpToCharacter } = this.props; - const itemsChanged = hasDifferentItems(prevProps.items, items); + const itemsChanged = hasDifferentItemsOrOrder(prevProps.items, items); const overviewOptionsChanged = !_.isMatch(prevProps.overviewOptions, overviewOptions); if ( diff --git a/frontend/src/Series/Index/Posters/SeriesIndexPosters.js b/frontend/src/Series/Index/Posters/SeriesIndexPosters.js index 986943a05..e1ec8c459 100644 --- a/frontend/src/Series/Index/Posters/SeriesIndexPosters.js +++ b/frontend/src/Series/Index/Posters/SeriesIndexPosters.js @@ -3,7 +3,7 @@ import React, { Component } from 'react'; import ReactDOM from 'react-dom'; import { Grid, WindowScroller } from 'react-virtualized'; import getIndexOfFirstCharacter from 'Utilities/Array/getIndexOfFirstCharacter'; -import hasDifferentItems from 'Utilities/Object/hasDifferentItems'; +import hasDifferentItemsOrOrder from 'Utilities/Object/hasDifferentItemsOrOrder'; import dimensions from 'Styles/Variables/dimensions'; import { sortDirections } from 'Helpers/Props'; import Measure from 'Components/Measure'; @@ -124,7 +124,7 @@ class SeriesIndexPosters extends Component { jumpToCharacter } = this.props; - const itemsChanged = hasDifferentItems(prevProps.items, items); + const itemsChanged = hasDifferentItemsOrOrder(prevProps.items, items); if ( prevProps.sortKey !== sortKey || diff --git a/frontend/src/Series/Index/SeriesIndex.js b/frontend/src/Series/Index/SeriesIndex.js index 3dcfdcb43..c696786cf 100644 --- a/frontend/src/Series/Index/SeriesIndex.js +++ b/frontend/src/Series/Index/SeriesIndex.js @@ -1,7 +1,7 @@ import _ from 'lodash'; import PropTypes from 'prop-types'; import React, { Component } from 'react'; -import hasDifferentItems from 'Utilities/Object/hasDifferentItems'; +import hasDifferentItemsOrOrder from 'Utilities/Object/hasDifferentItemsOrOrder'; import { align, icons, sortDirections } from 'Helpers/Props'; import LoadingIndicator from 'Components/Loading/LoadingIndicator'; import PageContent from 'Components/Page/PageContent'; @@ -67,10 +67,9 @@ class SeriesIndex extends Component { scrollTop } = this.props; - if ( - hasDifferentItems(prevProps.items, items) || - sortKey !== prevProps.sortKey || - sortDirection !== prevProps.sortDirection + if (sortKey !== prevProps.sortKey || + sortDirection !== prevProps.sortDirection || + hasDifferentItemsOrOrder(prevProps.items, items) ) { this.setJumpBarItems(); } diff --git a/frontend/src/Utilities/Object/hasDifferentItems.js b/frontend/src/Utilities/Object/hasDifferentItems.js index f89c99a10..826aab7c3 100644 --- a/frontend/src/Utilities/Object/hasDifferentItems.js +++ b/frontend/src/Utilities/Object/hasDifferentItems.js @@ -1,10 +1,19 @@ -import _ from 'lodash'; - function hasDifferentItems(prevItems, currentItems, idProp = 'id') { - const diff1 = _.differenceBy(prevItems, currentItems, (item) => item[idProp]); - const diff2 = _.differenceBy(currentItems, prevItems, (item) => item[idProp]); + if (prevItems === currentItems) { + return false; + } - return diff1.length > 0 || diff2.length > 0; + if (prevItems.length !== currentItems.length) { + return true; + } + + const currentItemIds = new Set(); + + currentItems.forEach((currentItem) => { + currentItemIds.add(currentItem[idProp]); + }); + + return prevItems.every((prevItem) => currentItemIds.has(prevItem[idProp])); } export default hasDifferentItems; diff --git a/frontend/src/Utilities/Object/hasDifferentItemsOrOrder.js b/frontend/src/Utilities/Object/hasDifferentItemsOrOrder.js new file mode 100644 index 000000000..e2acbc5c0 --- /dev/null +++ b/frontend/src/Utilities/Object/hasDifferentItemsOrOrder.js @@ -0,0 +1,21 @@ +function hasDifferentItemsOrOrder(prevItems, currentItems, idProp = 'id') { + if (prevItems === currentItems) { + return false; + } + + const len = prevItems.length; + + if (len !== currentItems.length) { + return true; + } + + for (let i = 0; i < len; i++) { + if (prevItems[i][idProp] !== currentItems[i][idProp]) { + return true; + } + } + + return false; +} + +export default hasDifferentItemsOrOrder;