perf(web): release inactive mutation state

This commit is contained in:
lingniu
2026-07-16 05:04:17 +08:00
parent 6f0c15fe6d
commit c4f6587120
3 changed files with 58 additions and 9 deletions

View File

@@ -0,0 +1,26 @@
import { QueryClientProvider, useMutation } from '@tanstack/react-query';
import { cleanup, fireEvent, render, screen, waitFor } from '@testing-library/react';
import { afterEach, expect, test } from 'vitest';
import { createPlatformQueryClient } from './AppV2';
afterEach(cleanup);
test('keeps mutation feedback while mounted and releases completed writes after route unmount', async () => {
const client = createPlatformQueryClient();
const retainedPayload = { rows: Array.from({ length: 500 }, (_, index) => ({ vin: `VIN-${index}`, model: `MODEL-${index}` })) };
function MutationHarness() {
const mutation = useMutation({ mutationFn: async () => retainedPayload });
return <div><button type="button" onClick={() => mutation.mutate()}></button>{mutation.data ? <span> {mutation.data.rows.length} </span> : null}</div>;
}
const view = render(<QueryClientProvider client={client}><MutationHarness /></QueryClientProvider>);
fireEvent.click(screen.getByRole('button', { name: '执行写操作' }));
expect(await screen.findByText('已处理 500 行')).toBeInTheDocument();
expect(client.getMutationCache().getAll()).toHaveLength(1);
view.unmount();
await waitFor(() => expect(client.getMutationCache().getAll()).toHaveLength(0));
client.clear();
});

View File

@@ -5,17 +5,26 @@ import { AuthGate } from './auth/AuthGate';
import { RoutePage } from './routing/RouteBoundary';
import { RoutePages } from './routing/routeModules';
import { ROUTER_FUTURE } from './routing/routerConfig';
import { QUERY_MEMORY } from './queryPolicy';
const queryClient = new QueryClient({
defaultOptions: {
queries: {
staleTime: 15_000,
gcTime: 5 * 60_000,
retry: 1,
refetchOnWindowFocus: false
export function createPlatformQueryClient() {
return new QueryClient({
defaultOptions: {
queries: {
staleTime: 15_000,
gcTime: 5 * 60_000,
retry: 1,
refetchOnWindowFocus: false
},
mutations: {
gcTime: QUERY_MEMORY.highVolumeGcTime,
retry: 0
}
}
}
});
});
}
const queryClient = createPlatformQueryClient();
export function AppV2() {
return (