From f5cfad326cf4b26d70f06bc144985f73296ae20a Mon Sep 17 00:00:00 2001 From: Lei Nelissen Date: Sun, 5 Jul 2020 22:25:47 +0200 Subject: [PATCH] Add small performance improvement to album list --- .eslintrc.js | 4 +- index.ts | 9 +++++ package-lock.json | 14 +++++-- package.json | 1 + src/screens/Music/stacks/Albums.tsx | 57 ++++++++++++++++------------- 5 files changed, 55 insertions(+), 30 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 69b9353..d3105eb 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -7,6 +7,7 @@ module.exports = { 'eslint:recommended', 'plugin:react/recommended', 'plugin:@typescript-eslint/eslint-recommended', + 'plugin:react-hooks/recommended', // "plugin:@typescript-eslint/recommended" ], globals: { @@ -23,7 +24,8 @@ module.exports = { }, plugins: [ 'react', - '@typescript-eslint' + '@typescript-eslint', + 'react-hooks' ], rules: { indent: [ diff --git a/index.ts b/index.ts index f16aef1..cdf75df 100644 --- a/index.ts +++ b/index.ts @@ -1,3 +1,12 @@ +// import React from 'react'; + +// // if (process.env.NODE_ENV === 'development') { +// // const whyDidYouRender = require('@welldone-software/why-did-you-render'); +// // whyDidYouRender(React, { +// // trackAllPureComponents: true, +// // }); +// // } + import 'react-native-gesture-handler'; import { AppRegistry } from 'react-native'; import TrackPlayer from 'react-native-track-player'; diff --git a/package-lock.json b/package-lock.json index f779078..22a07d4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1638,6 +1638,14 @@ "eslint-plugin-react-hooks": "^3.0.0", "eslint-plugin-react-native": "3.8.1", "prettier": "^2.0.2" + }, + "dependencies": { + "eslint-plugin-react-hooks": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-3.0.0.tgz", + "integrity": "sha512-EjxTHxjLKIBWFgDJdhKKzLh5q+vjTFrqNZX36uIxWS4OfyXe5DawqPj3U5qeJ1ngLwatjzQnmR0Lz0J0YH3kxw==", + "dev": true + } } }, "@react-native-community/eslint-plugin": { @@ -3943,9 +3951,9 @@ } }, "eslint-plugin-react-hooks": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-3.0.0.tgz", - "integrity": "sha512-EjxTHxjLKIBWFgDJdhKKzLh5q+vjTFrqNZX36uIxWS4OfyXe5DawqPj3U5qeJ1ngLwatjzQnmR0Lz0J0YH3kxw==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.0.5.tgz", + "integrity": "sha512-3YLSjoArsE2rUwL8li4Yxx1SUg3DQWp+78N3bcJQGWVZckcp+yeQGsap/MSq05+thJk57o+Ww4PtZukXGL02TQ==", "dev": true }, "eslint-plugin-react-native": { diff --git a/package.json b/package.json index 3ad4997..744ded2 100644 --- a/package.json +++ b/package.json @@ -59,6 +59,7 @@ "babel-jest": "^24.9.0", "babel-plugin-module-resolver": "^4.0.0", "eslint": "^6.5.1", + "eslint-plugin-react-hooks": "^4.0.5", "jest": "^24.9.0", "metro-react-native-babel-preset": "^0.58.0", "react-test-renderer": "16.11.0", diff --git a/src/screens/Music/stacks/Albums.tsx b/src/screens/Music/stacks/Albums.tsx index 7623a9c..46797ab 100644 --- a/src/screens/Music/stacks/Albums.tsx +++ b/src/screens/Music/stacks/Albums.tsx @@ -14,6 +14,7 @@ import AlbumImage, { AlbumItem } from './components/AlbumImage'; import { selectAlbumsByAlphabet, SectionedId } from 'store/music/selectors'; import AlphabetScroller from 'components/AlphabetScroller'; import { EntityId } from '@reduxjs/toolkit'; +import styled from 'styled-components/native'; interface VirtualizedItemInfo { section: SectionedId, @@ -33,18 +34,31 @@ type VirtualizedSectionList = { _subExtractor: (index: number) => VirtualizedIte function generateSection({ section }: { section: SectionedId }) { return ( - + ); } -class SectionHeading extends PureComponent<{ label: string }> { +const SectionContainer = styled.View` + background-color: #f6f6f6; + border-bottom-color: #eee; + border-bottom-width: 1px; + height: 50px; + justify-content: center; +`; + +const SectionText = styled.Text` + font-size: 24px; + font-weight: bold; +`; + +class SectionHeading extends PureComponent<{ label: string }> { render() { const { label } = this.props; return ( - - {label} - + + {label} + ); } } @@ -57,6 +71,10 @@ interface GeneratedAlbumItemProps { onPress: (id: string) => void; } +const HalfOpacity = styled.Text` + opacity: 0.5; +`; + class GeneratedAlbumItem extends PureComponent { render() { const { id, imageUrl, name, artist, onPress } = this.props; @@ -66,25 +84,13 @@ class GeneratedAlbumItem extends PureComponent { {name} - {artist} + {artist} ); } } -// const getItemLayout: any = sectionListGetItemLayout({ -// getItemHeight: (rowData, sectionIndex, rowIndex) => { -// console.log(sectionIndex, rowIndex, rowData); -// if (sectionIndex === 0) { return 0; } -// else if (rowIndex % 2 > 0) { return 0; } -// return 220; -// }, -// getSectionHeaderHeight: () => 50, -// // getSeparatorHeight: () => 1 / PixelRatio.get(), -// // listHeaderHeight: 0, -// }); - const Albums: React.FC = () => { // Retrieve data from store const { entities: albums } = useTypedSelector((state) => state.music.albums); @@ -120,6 +126,7 @@ const Albums: React.FC = () => { // current item. const previousRows = data?.filter((row, i) => i < sectionIndex) .reduce((sum, row) => sum + Math.ceil(row.data.length / 2), 0) || 0; + // We must also calcuate the offset, total distance from the top of the // screen. First off, we'll account for each sectionIndex that is shown up @@ -130,8 +137,6 @@ const Albums: React.FC = () => { const itemOffset = 220 * (previousRows + currentRows); const offset = headingOffset + itemOffset; - // console.log(index, sectionIndex, itemIndex, previousRows, currentRows, offset); - return { index, length, offset }; }, [listRef]); @@ -141,14 +146,14 @@ const Albums: React.FC = () => { const selectLetter = useCallback((sectionIndex: number) => { listRef.current?.scrollToLocation({ sectionIndex, itemIndex: 0, animated: false, }); }, [listRef]); - const generateItem = ({ item, index, section }: { item: EntityId, index: number, section: SectionedId }) => { + const generateItem = useCallback(({ item, index, section }: { item: EntityId, index: number, section: SectionedId }) => { if (index % 2 === 1) { - return null; + return ; } const nextItem = section.data[index + 1]; return ( - + { } ); - }; + }, [albums, getImage, selectAlbum]); // Retrieve data on mount useEffect(() => { @@ -175,7 +180,7 @@ const Albums: React.FC = () => { if (!lastRefreshed || differenceInDays(lastRefreshed, new Date()) > ALBUM_CACHE_AMOUNT_OF_DAYS) { retrieveData(); } - }, []); + }); return ( @@ -186,8 +191,8 @@ const Albums: React.FC = () => { refreshing={isLoading} onRefresh={retrieveData} getItemLayout={getItemLayout} - keyExtractor={(d) => d as string} ref={listRef} + keyExtractor={(item, index) => `${item}_${index}`} onScrollToIndexFailed={console.log} renderSectionHeader={generateSection} renderItem={generateItem}