perf: Additional optimizations to reduce React violations and improve performance - Add early return for empty songs array in totalDuration calculation - Add null check for getAllPlaylists to prevent unnecessary processing - Use requestAnimationFrame in Intersection Observer for better performance - Should reduce 600-1400ms message handler violations

This commit is contained in:
Geert Rademakes 2025-08-06 11:10:28 +02:00
parent 770c606561
commit 4c3b3e31d4

View File

@ -145,6 +145,8 @@ export const PaginatedSongList: React.FC<PaginatedSongListProps> = memo(({
// Memoized helper function to get all playlists (excluding folders) from the playlist tree
const getAllPlaylists = useCallback((nodes: PlaylistNode[]): PlaylistNode[] => {
if (!nodes || nodes.length === 0) return [];
let result: PlaylistNode[] = [];
for (const node of nodes) {
if (node.type === 'playlist') {
@ -222,6 +224,9 @@ export const PaginatedSongList: React.FC<PaginatedSongListProps> = memo(({
if (totalPlaylistDuration) {
return totalPlaylistDuration;
}
// Only calculate if we have songs and no total duration provided
if (songs.length === 0) return '';
// Fallback to calculating from current songs
const totalSeconds = songs.reduce((total, song) => {
if (!song.totalTime) return total;
@ -247,7 +252,7 @@ export const PaginatedSongList: React.FC<PaginatedSongListProps> = memo(({
}
}, [debouncedSearchQuery, searchQuery, onSearch]);
// Intersection Observer for infinite scroll
// Intersection Observer for infinite scroll - optimized
useEffect(() => {
if (loadingRef.current) {
observerRef.current = new IntersectionObserver(
@ -255,7 +260,10 @@ export const PaginatedSongList: React.FC<PaginatedSongListProps> = memo(({
// Use current values from refs to avoid stale closure
if (entries[0].isIntersecting && hasMoreRef.current && !loadingRef_state.current && !isTriggeringRef.current) {
isTriggeringRef.current = true;
onLoadMoreRef.current();
// Use requestAnimationFrame for better performance
requestAnimationFrame(() => {
onLoadMoreRef.current();
});
// Reset the flag after a short delay to prevent multiple triggers
timeoutRef.current = setTimeout(() => {
isTriggeringRef.current = false;