fix(mobile): stop full scene-list refetch on back-navigation (perf)

Returning to the Scenes list from a scene caused a full reload + phone load spike (report 5df48551). Cause: invalidateQueries(['scenes']) in SceneDetail/Player/Performer/Studio handlers — including the silent auto-enrich-thumbnail that fires on opening any thumbnail-less scene — forces react-query to refetch EVERY loaded page of the infinite list. Added refetchType:'none' to all ['scenes'] invalidations: marks stale without refetching the active list, which refreshes on pull-to-refresh / filter change instead. Scene detail (['scene', id]) still updates immediately.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
jtrzupek 2026-06-20 14:14:07 +02:00
parent c524b43fa3
commit b0e15935c6
5 changed files with 18 additions and 8 deletions

View file

@ -16,6 +16,13 @@ export type ChangelogEntry = {
};
export const CHANGELOG: ChangelogEntry[] = [
{
id: '2026-06-20',
date: 'June 2026',
items: [
'Going back to the list from a scene no longer reloads everything or slows the phone.',
],
},
{
id: '2026-06-19',
date: 'June 2026',

View file

@ -62,7 +62,7 @@ export function PerformerScenesScreen() {
const blacklistMutation = useMutation({
mutationFn: () => client.addBlacklist('performer', id),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['scenes'] });
queryClient.invalidateQueries({ queryKey: ['scenes'], refetchType: 'none' });
queryClient.invalidateQueries({ queryKey: ['performer-scenes', id] });
queryClient.invalidateQueries({ queryKey: ['performer-movies', id] });
navigation.goBack();

View file

@ -69,7 +69,10 @@ function useMarkSourceBroken(params: RouteParams) {
await client.markPlaybackDead(params.sceneId, params.playbackId);
queryClient.invalidateQueries({ queryKey: ['scene', params.sceneId] });
}
queryClient.invalidateQueries({ queryKey: ['scenes'] });
// refetchType:'none' — oznacz stale bez wymuszania refetcha całej infinite-listy
// (po powrocie do Scenes powodowało przeładowanie wszystkich stron = obciążenie,
// bug-report 5df48551). Lista odświeży się przy pull-to-refresh / zmianie filtra.
queryClient.invalidateQueries({ queryKey: ['scenes'], refetchType: 'none' });
} catch {
// best-effort — i tak wracamy; źródło zostanie do następnej próby
} finally {

View file

@ -47,7 +47,7 @@ export function SceneDetailScreen() {
mutationFn: () => (isFav ? client.removeSceneFavorite(id) : client.addSceneFavorite(id)),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['scene', id] });
queryClient.invalidateQueries({ queryKey: ['scenes'] });
queryClient.invalidateQueries({ queryKey: ['scenes'], refetchType: 'none' });
},
});
@ -105,7 +105,7 @@ export function SceneDetailScreen() {
onSuccess: (out) => {
if (out.thumbnail_url) {
queryClient.invalidateQueries({ queryKey: ['scene', id] });
queryClient.invalidateQueries({ queryKey: ['scenes'] });
queryClient.invalidateQueries({ queryKey: ['scenes'], refetchType: 'none' });
}
},
});
@ -126,7 +126,7 @@ export function SceneDetailScreen() {
mutationFn: () => client.enrichSceneThumbnail(id, true),
onSuccess: (out) => {
queryClient.invalidateQueries({ queryKey: ['scene', id] });
queryClient.invalidateQueries({ queryKey: ['scenes'] });
queryClient.invalidateQueries({ queryKey: ['scenes'], refetchType: 'none' });
Alert.alert(
'Thumbnail',
out.thumbnail_url ? 'Refreshed from the source page.' : 'Could not fetch a fresh thumbnail.',
@ -697,7 +697,7 @@ function PlaybackButton({
'The tube removed this video. We marked the source, you won\'t see it again.',
);
queryClient.invalidateQueries({ queryKey: ['scene', sceneId] });
queryClient.invalidateQueries({ queryKey: ['scenes'] });
queryClient.invalidateQueries({ queryKey: ['scenes'], refetchType: 'none' });
return;
}
// 503 = transient extraction failure (hoster chwilowo niedostępny, network
@ -789,7 +789,7 @@ function PlaybackButton({
try {
await client.markPlaybackDead(sceneId, source.id);
queryClient.invalidateQueries({ queryKey: ['scene', sceneId] });
queryClient.invalidateQueries({ queryKey: ['scenes'] });
queryClient.invalidateQueries({ queryKey: ['scenes'], refetchType: 'none' });
} catch (e) {
Alert.alert('Failed', e instanceof Error ? e.message : String(e));
}

View file

@ -55,7 +55,7 @@ export function StudioScenesScreen() {
const blacklistMutation = useMutation({
mutationFn: () => client.addBlacklist('studio', studioId),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['scenes'] });
queryClient.invalidateQueries({ queryKey: ['scenes'], refetchType: 'none' });
queryClient.invalidateQueries({ queryKey: ['studio-scenes', slug] });
navigation.goBack();
},