Skip to content

Commit

Permalink
perf: Stablise props that change in expensive components
Browse files Browse the repository at this point in the history
Most of the work here is memoising props to expensive components like
`FlatList`, and `StoryView`, and also using `React.memo` on components
to avoid rendering them at all in circumstances that don't involve them.
  • Loading branch information
Jonathan Jacobs committed Feb 16, 2023
1 parent 9ce9d27 commit a04e092
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -84,16 +84,16 @@ const OnDeviceUI = ({
}: OnDeviceUIProps) => {
const [tabOpen, setTabOpen] = useState(initialTabOpen || PREVIEW);
const [slideBetweenAnimation, setSlideBetweenAnimation] = useState(false);
const [previewDimensions, setPreviewDimensions] = useState<PreviewDimens>({
const [previewDimensions, setPreviewDimensions] = useState<PreviewDimens>(() => ({
width: Dimensions.get('window').width,
height: Dimensions.get('window').height,
});
}));
const animatedValue = useRef(new Animated.Value(tabOpen));
const wide = useWindowDimensions().width >= BREAKPOINT;
const insets = useSafeAreaInsets();
const [isUIVisible, setIsUIVisible] = useState(isUIHidden !== undefined ? !isUIHidden : true);

const handleToggleTab = (newTabOpen: number) => {
const handleToggleTab = React.useCallback((newTabOpen: number) => {
if (newTabOpen === tabOpen) {
return;
}
Expand All @@ -110,7 +110,7 @@ const OnDeviceUI = ({
if (newTabOpen === PREVIEW) {
Keyboard.dismiss();
}
};
}, [tabOpen]);

const noSafeArea = context?.parameters?.noSafeArea ?? false;
const previewWrapperStyles = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,13 @@ const AbsolutePositionedKeyboardAwareView = ({
children,
}: Props) => {
const onLayoutHandler = ({ nativeEvent }: LayoutChangeEvent) => {
onLayout({
height: nativeEvent.layout.height,
width: nativeEvent.layout.width,
});
const {height: layoutHeight, width: layoutWidth} = nativeEvent.layout;
if (layoutHeight !== height || layoutWidth !== width) {
onLayout({
height: layoutHeight,
width: layoutWidth,
});
}
};

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,10 @@ const styles = StyleSheet.create({
const tabBarHeight = 40;

const StoryListView = ({ selectedStoryContext, storyIndex }: Props) => {
function keyExtractor(item: any, index) {
return item.id + index;
}

const insets = useSafeAreaInsets();
const originalData = useMemo(() => getStories(storyIndex), [storyIndex]);
const [data, setData] = useState<DataItem[]>(originalData);
Expand Down Expand Up @@ -167,7 +171,27 @@ const StoryListView = ({ selectedStoryContext, storyIndex }: Props) => {
channel.emit(Events.SET_CURRENT_STORY, { storyId });
};

const safeStyle = { flex: 1, marginTop: insets.top, paddingBottom: insets.bottom + tabBarHeight };
const safeStyle = React.useMemo(() => {
return { flex: 1, marginTop: insets.top, paddingBottom: insets.bottom + tabBarHeight };
}, [insets]);

const renderItem: SectionListRenderItem<StoryIndexEntry, DataItem> = React.useCallback(({item}) => {
return (
<ListItem
title={item.name}
kind={item.title}
selected={selectedStoryContext && item.id === selectedStoryContext.id}
onPress={() => changeStory(item.id)}
/>
);
}, []);

const renderSectionHeader = React.useCallback(({ section: { title } }) => (
<SectionHeader
title={title}
selected={selectedStoryContext && title === selectedStoryContext.title}
/>
), []);

return (
<StoryListContainer>
Expand All @@ -184,21 +208,9 @@ const StoryListView = ({ selectedStoryContext, storyIndex }: Props) => {
// contentInset={{ bottom: insets.bottom, top: 0 }}
style={styles.sectionList}
testID="Storybook.ListView"
renderItem={({ item }) => (
<ListItem
title={item.name}
kind={item.title}
selected={selectedStoryContext && item.id === selectedStoryContext.id}
onPress={() => changeStory(item.id)}
/>
)}
renderSectionHeader={({ section: { title } }) => (
<SectionHeader
title={title}
selected={selectedStoryContext && title === selectedStoryContext.title}
/>
)}
keyExtractor={(item, index) => item.id + index}
renderItem={renderItem}
renderSectionHeader={renderSectionHeader}
keyExtractor={keyExtractor}
sections={data}
stickySectionHeadersEnabled={false}
/>
Expand All @@ -207,4 +219,4 @@ const StoryListView = ({ selectedStoryContext, storyIndex }: Props) => {
);
};

export default StoryListView;
export default React.memo(StoryListView);
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,4 @@ const StoryView = ({ context }: Props) => {
);
};

export default StoryView;
export default React.memo(StoryView);

0 comments on commit a04e092

Please sign in to comment.