QueryClienthas no default configuration, using React Query defaults:staleTime: 0(everything refetches immediately)refetchOnWindowFocus: true(refetch every time user returns to tab)refetchOnMount: true(refetch on every component mount)
- This causes excessive unnecessary refetches
- 29 instances of
refetchInterval: 5000(5 seconds) - Found in modals that poll even when closed
- Balance checks, allowances, and deposit amounts all polling at 5s
src/config/polling.tsexists with sensible intervals but is rarely used- Hardcoded intervals scattered throughout codebase (99+ instances)
- Deposit/Withdraw modals continue polling even when closed
- Should use conditional intervals:
refetchInterval: isOpen ? 5000 : false
// src/components/Web3Provider.tsx
const queryClient = new QueryClient({
defaultOptions: {
queries: {
staleTime: 30000, // Data fresh for 30s (reduces refetches)
cacheTime: 5 * 60 * 1000, // Cache for 5 minutes
refetchOnWindowFocus: false, // Don't refetch on tab focus (biggest win)
refetchOnMount: false, // Don't refetch on component remount
retry: 1, // Reduce retries from 3 to 1
refetchInterval: false, // Disable interval by default
},
},
})Impact: Could reduce requests by 50-70% immediately
// Example: GenesisDepositModal.tsx
const { data: allowanceData } = useContractRead({
// ...
query: {
refetchInterval: isOpen ? 15000 : false, // Poll only when open
staleTime: 10000,
}
});Files to update:
src/components/GenesisDepositModal.tsx(2 instances at 5000ms)src/components/AnchorDepositWithdrawModal.tsx(17 instances at 5000ms)src/components/SailManageModal.tsx(2 instances at 5000ms)src/components/AnchorDepositModal.tsx(5 instances at 5000ms)src/components/AnchorWithdrawModal.tsx(1 instance at 5000ms)
Impact: Eliminates polling when modals closed
Change aggressive 5-second intervals to more reasonable values:
// Balance checks: 5s → 15s
refetchInterval: 15000
// Allowances: 5s → 15s (only checked when needed)
refetchInterval: 15000
// Prices: 30s (already reasonable in most places)
refetchInterval: 30000
// Genesis end check: 5s → 60s (doesn't change minute-to-minute)
refetchInterval: 60000Files:
src/app/genesis/page.tsx- genesis end check (5s → 60s)- Modal balance checks (5s → conditional 15s)
import { POLLING_INTERVALS } from '@/config/polling';
// Instead of:
refetchInterval: 5000
// Use:
refetchInterval: POLLING_INTERVALS.NORMALAlready using useContractReads in many places (good!), but consider:
// Instead of 3 separate calls:
useContractRead({ address: token1, functionName: 'balanceOf' })
useContractRead({ address: token2, functionName: 'balanceOf' })
useContractRead({ address: token3, functionName: 'balanceOf' })
// Use single batched call:
useContractReads({
contracts: [
{ address: token1, functionName: 'balanceOf' },
{ address: token2, functionName: 'balanceOf' },
{ address: token3, functionName: 'balanceOf' },
]
})For data that never changes:
- Token symbols
- Token decimals
- Token names
const { data: tokenSymbol } = useContractRead({
// ...
query: {
staleTime: Infinity, // Never refetch
cacheTime: Infinity, // Cache forever
}
});- Add QueryClient default configuration
- Add conditional polling to GenesisDepositModal
- Update all modal polling to be conditional
- Increase genesis end check interval to 60s
- Test modal behavior thoroughly
- Gradually replace hardcoded intervals with centralized config
- Identify and cache static contract data
| Optimization | Request Reduction | Effort |
|---|---|---|
| QueryClient defaults | 50-70% | 5 min |
| Conditional modal polling | 30-40% | 30 min |
| Increased intervals | 10-20% | 15 min |
| Batching improvements | 5-10% | Varies |
Total potential reduction: 60-80% of current RPC requests
After implementing, monitor:
- Alchemy dashboard for request count trends
- User-reported latency issues
- Data freshness (ensure nothing feels stale)
- The polling config file already exists at
src/config/polling.tswith good documentation - Most queries already use
allowFailure: true(good for reliability) - Many queries already use
useContractReadsfor batching (good!) - Current setup favors freshness over efficiency - we can rebalance