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