perf(frontend): start playlist data load immediately on selection; useLayoutEffect for faster playlist switch

This commit is contained in:
Geert Rademakes 2025-08-13 15:35:27 +02:00
parent 52953d7e0d
commit 449dfc708e
2 changed files with 28 additions and 3 deletions

View File

@ -130,7 +130,8 @@ const RekordboxReader: React.FC = () => {
loadNextPage,
searchSongs,
searchQuery,
refresh
refresh,
switchPlaylistImmediately
} = usePaginatedSongs({ pageSize: 100, playlistName: currentPlaylist });
// Export library to XML
@ -209,6 +210,10 @@ const RekordboxReader: React.FC = () => {
// Clear selected song immediately to prevent stale state
setSelectedSong(null);
// Kick off data load immediately to avoid delay before backend call
const target = name || "All Songs";
switchPlaylistImmediately(target);
// Navigate immediately without any delays
if (name === "All Songs") {
navigate("/", { replace: true });

View File

@ -1,4 +1,4 @@
import { useState, useEffect, useCallback, useRef } from 'react';
import { useState, useEffect, useLayoutEffect, useCallback, useRef } from 'react';
import { api, type SongsResponse } from '../services/api';
import type { Song } from '../types/interfaces';
@ -139,7 +139,7 @@ export const usePaginatedSongs = (options: UsePaginatedSongsOptions = {}) => {
}, []);
// Handle playlist changes - streamlined for immediate response
useEffect(() => {
useLayoutEffect(() => {
if (previousPlaylistRef.current !== playlistName) {
// Update refs immediately
currentPlaylistRef.current = playlistName;
@ -160,6 +160,25 @@ export const usePaginatedSongs = (options: UsePaginatedSongsOptions = {}) => {
}
}, [playlistName, initialSearch, loadPage]);
// Imperative method to switch playlist and start loading immediately
const switchPlaylistImmediately = useCallback((targetPlaylistName: string) => {
// Update refs immediately so effect does not double-trigger
currentPlaylistRef.current = targetPlaylistName;
previousPlaylistRef.current = targetPlaylistName;
currentSearchQueryRef.current = searchQuery;
// Clear state for instant visual feedback
setSongs([]);
setTotalSongs(0);
setTotalDuration(undefined);
setHasMore(true);
setCurrentPage(1);
setError(null);
// Start loading right away
loadPage(1, initialSearch, targetPlaylistName);
}, [initialSearch, loadPage, searchQuery]);
return {
songs,
loading,
@ -174,5 +193,6 @@ export const usePaginatedSongs = (options: UsePaginatedSongsOptions = {}) => {
searchSongs,
reset,
refresh: () => loadPage(1)
, switchPlaylistImmediately
};
};