perf(suggestions): limit to top 5 artists and reduce rate limiting

Major optimizations:
- Extract only top 5 artists by track frequency instead of all artists
- Use faster rate limiter (200ms) when using MusicBrainz proxy
- Remove skip_vector_build since we now have manageable artist count

Expected load time: ~5-8 seconds for first load with 5 artists
vs previous: 50+ seconds with 50 artists
This commit is contained in:
vicrodh committed 2026-01-27 13:20:16 -06:00
1 parent 7506d69e53
commit b551df71c0
4 files changed
+66 -22

No files matched your search

@@ -97,7 +97,7 @@
artists,
excludeTrackIds,
showReasons,
{ max_pool_size: poolSize, skip_vector_build: true }
{ max_pool_size: poolSize }
);
const elapsed = ((performance.now() - startTime) / 1000).toFixed(2);
log(`Backend returned in ${elapsed}s:`, {
@@ -8,7 +8,7 @@
import { open } from '@tauri-apps/plugin-dialog';
import TrackRow from '../TrackRow.svelte';
import PlaylistSuggestions from '../PlaylistSuggestions.svelte';
import { extractUniqueArtists } from '$lib/services/playlistSuggestionsService';
import { extractTopArtists } from '$lib/services/playlistSuggestionsService';
import { type OfflineCacheStatus } from '$lib/stores/offlineCacheState';
import {
subscribe as subscribeOffline,
@@ -194,9 +194,9 @@
let localTracksDuration = $derived(localTracks.reduce((sum, t) => sum + t.duration_secs, 0));
let totalDuration = $derived((playlist?.duration ?? 0) + localTracksDuration);
// Playlist suggestions: extract unique artists from Qobuz tracks (not local)
// Playlist suggestions: extract top 5 artists by track count (not local tracks)
const playlistArtists = $derived(
extractUniqueArtists(tracks.filter(t => !t.isLocal))
extractTopArtists(tracks.filter(t => !t.isLocal), 5)
);
// Track IDs to exclude from suggestions (already in playlist)
const excludeTrackIds = $derived(
+41 -15
View File
@@ -157,26 +157,52 @@ export async function cleanupVectorStore(maxAgeDays?: number): Promise<number> {
// ============ Helpers ============
/** Default number of top artists to use for suggestions */
const DEFAULT_TOP_ARTISTS = 5;
/**
* Extract unique artists from playlist tracks
* Extract top artists from playlist tracks, sorted by frequency (track count)
*
* @param tracks - Playlist tracks
* @param limit - Maximum number of artists to return (default: 5)
*/
export function extractTopArtists(
tracks: Array<{ artist?: string; artistId?: number }>,
limit: number = DEFAULT_TOP_ARTISTS
): PlaylistArtist[] {
// Count tracks per artist
const artistCounts = new Map<string, { count: number; qobuzId?: number }>();
for (const track of tracks) {
if (track.artist) {
const existing = artistCounts.get(track.artist);
if (existing) {
existing.count++;
} else {
artistCounts.set(track.artist, { count: 1, qobuzId: track.artistId });
}
}
}
// Sort by count descending, take top N
const sorted = [...artistCounts.entries()]
.sort((a, b) => b[1].count - a[1].count)
.slice(0, limit);
return sorted.map(([name, data]) => ({
name,
qobuzId: data.qobuzId
}));
}
/**
* Extract unique artists from playlist tracks (legacy, use extractTopArtists instead)
* @deprecated Use extractTopArtists for better performance
*/
export function extractUniqueArtists(
tracks: Array<{ artist?: string; artistId?: number }>
): PlaylistArtist[] {
const seen = new Set<string>();
const artists: PlaylistArtist[] = [];
for (const track of tracks) {
if (track.artist && !seen.has(track.artist)) {
seen.add(track.artist);
artists.push({
name: track.artist,
qobuzId: track.artistId
});
}
}
return artists;
return extractTopArtists(tracks, Infinity);
}
/**