perf: Optimize playlist manager to fix 727ms click handler delay - Memoize button styles to prevent object recreation on every render - Wrap PlaylistItem in React.memo to prevent unnecessary re-renders - Fixes React violation 'click' handler took 727ms - Should dramatically improve playlist switching responsiveness

This commit is contained in:
Geert Rademakes 2025-08-06 10:52:11 +02:00
parent 586b3634b5
commit 510c6e1026

View File

@ -36,27 +36,50 @@ interface PlaylistManagerProps {
onPlaylistMove: (playlistName: string, targetFolderName: string | null) => void;
}
const getButtonStyles = (isSelected: boolean) => ({
// Memoized button styles to prevent unnecessary re-renders
const selectedButtonStyles = {
width: "100%",
display: "flex",
alignItems: "center",
justifyContent: "space-between",
bg: isSelected ? "blue.800" : "transparent",
color: isSelected ? "white" : "gray.100",
fontWeight: isSelected ? "600" : "normal",
bg: "blue.800",
color: "white",
fontWeight: "600",
borderRadius: "md",
px: 4,
py: 2,
cursor: "pointer",
transition: "all 0.2s",
_hover: {
bg: isSelected ? "blue.600" : "whiteAlpha.200",
bg: "blue.600",
transform: "translateX(2px)",
},
_active: {
bg: isSelected ? "blue.700" : "whiteAlpha.300",
bg: "blue.700",
},
});
};
const unselectedButtonStyles = {
width: "100%",
display: "flex",
alignItems: "center",
justifyContent: "space-between",
bg: "transparent",
color: "gray.100",
fontWeight: "normal",
borderRadius: "md",
px: 4,
py: 2,
cursor: "pointer",
transition: "all 0.2s",
_hover: {
bg: "whiteAlpha.200",
transform: "translateX(2px)",
},
_active: {
bg: "whiteAlpha.300",
},
};
interface PlaylistItemProps {
node: PlaylistNode;
@ -68,7 +91,7 @@ interface PlaylistItemProps {
allFolders: { name: string }[];
}
const PlaylistItem: React.FC<PlaylistItemProps> = ({
const PlaylistItem: React.FC<PlaylistItemProps> = React.memo(({
node,
level,
selectedItem,
@ -86,7 +109,7 @@ const PlaylistItem: React.FC<PlaylistItemProps> = ({
<Flex align="center" gap={1}>
<Button
flex={1}
{...getButtonStyles(false)}
{...unselectedButtonStyles}
onClick={() => setIsOpen(!isOpen)}
ml={indent}
pl={level > 0 ? 6 : 4} // Add extra padding for nested items
@ -154,7 +177,7 @@ const PlaylistItem: React.FC<PlaylistItemProps> = ({
<Flex align="center" gap={0}>
<Button
flex="1 1 auto"
{...getButtonStyles(selectedItem === node.name)}
{...(selectedItem === node.name ? selectedButtonStyles : unselectedButtonStyles)}
onClick={() => onPlaylistSelect(node.name)}
ml={indent}
pl={level > 0 ? 6 : 4} // Add extra padding for nested items
@ -237,7 +260,7 @@ const PlaylistItem: React.FC<PlaylistItemProps> = ({
</Menu>
</Flex>
);
};
});
export const PlaylistManager: React.FC<PlaylistManagerProps> = ({
playlists,
@ -289,7 +312,7 @@ export const PlaylistManager: React.FC<PlaylistManagerProps> = ({
<Box>
<VStack spacing={2} align="stretch" mb={4}>
<Button
{...getButtonStyles(selectedItem === null)}
{...(selectedItem === null ? selectedButtonStyles : unselectedButtonStyles)}
onClick={() => onPlaylistSelect(null)}
>
All Songs