Documentation Index
Fetch the complete documentation index at: https://docs.privacyboost.io/llms.txt
Use this file to discover all available pages before exploring further.
Performance Optimization
This guide covers performance optimization strategies for the Privacy Boost TypeScript SDK.
WASM Loading
Lazy Loading
The WASM module is large. Load it only when needed:
// Don't import at top level in routes that don't need it
// Instead, dynamically import when needed
async function initPrivacy() {
const { PrivacyBoost } = await import('@sunnyside-io/privacy-boost');
return await PrivacyBoost.create(config);
}
Preloading
For routes that will need the SDK, preload in the background:
// In your app initialization
function preloadSDK() {
// Preload WASM in background
import('@sunnyside-io/privacy-boost').then(({ loadWasm }) => {
loadWasm().catch(() => {
// Ignore preload errors
});
});
}
// Call early in your app
useEffect(() => {
preloadSDK();
}, []);
Code Splitting
Use route-based code splitting:
// React Router example
const PrivacyWallet = React.lazy(() => import('./PrivacyWallet'));
function App() {
return (
<Routes>
<Route path="/wallet" element={
<Suspense fallback={<Loading />}>
<PrivacyWallet />
</Suspense>
} />
</Routes>
);
}
Balance Caching
Local Cache
The SDK caches balances automatically. Control cache behavior:
// Get cached balance (fast)
const cachedBalance = useBalanceStore.getState().balances.get(tokenAddress);
// Force refresh from server (slow)
await sdk.vault.refreshBalance(tokenAddress);
const freshBalance = await sdk.vault.getBalance(tokenAddress);
Smart Refresh
Only refresh when needed:
const CACHE_DURATION = 30000; // 30 seconds
function useBalance(tokenAddress: string) {
const [balance, setBalance] = useState<bigint>(0n);
const lastFetch = useRef<number>(0);
const refresh = useCallback(async () => {
const now = Date.now();
if (now - lastFetch.current < CACHE_DURATION) {
return; // Use cached
}
await sdk.vault.refreshBalance(tokenAddress);
setBalance(await sdk.vault.getBalance(tokenAddress));
lastFetch.current = now;
}, [tokenAddress]);
return { balance, refresh };
}
Batch Operations
Sync all balances at once instead of individually:
// SLOW - Multiple requests
for (const token of tokens) {
await sdk.vault.refreshBalance(token);
}
// FAST - Single batch request
await sdk.vault.refreshBalances();
Network Optimization
Request Debouncing
import { debounce } from 'lodash';
const debouncedSearch = useMemo(
() => debounce(async (query: string) => {
const result = await sdk.resolveIdentity(query);
setSearchResult(result);
}, 300),
[]
);
function AddressSearch() {
return (
<input
type="text"
onChange={(e) => debouncedSearch(e.target.value)}
placeholder="Search address..."
/>
);
}
Request Deduplication
const pendingRequests = new Map<string, Promise<unknown>>();
async function deduplicatedRequest<T>(
key: string,
request: () => Promise<T>
): Promise<T> {
if (pendingRequests.has(key)) {
return pendingRequests.get(key) as Promise<T>;
}
const promise = request().finally(() => {
pendingRequests.delete(key);
});
pendingRequests.set(key, promise);
return promise;
}
// Usage
const balance = await deduplicatedRequest(
`balance:${tokenAddress}`,
() => sdk.vault.getBalance(tokenAddress)
);
Parallel Requests
// SLOW - Sequential
const balance1 = await sdk.vault.getBalance(token1);
const balance2 = await sdk.vault.getBalance(token2);
const balance3 = await sdk.vault.getBalance(token3);
// FAST - Parallel
const [balance1, balance2, balance3] = await Promise.all([
sdk.vault.getBalance(token1),
sdk.vault.getBalance(token2),
sdk.vault.getBalance(token3),
]);
Memory Management
Cleanup Subscriptions
useEffect(() => {
const unsubscribe = useBalanceStore.subscribe((state) => {
// Handle changes
});
return () => unsubscribe(); // Important!
}, []);
Clear Unused Data
// Clear balances when clearing session
async function clearSession() {
await sdk.auth.clearSession();
useBalanceStore.getState().clearBalances();
useTransactionStore.getState().clearTransactions();
}
Limit History Size
// Fetch only what you need
const recentTxs = await sdk.transactions.fetchHistory({
limit: 20, // Don't fetch everything
});
Bundle Size
Tree Shaking
Import only what you need:
// BAD - Imports entire package
import * as SDK from '@sunnyside-io/privacy-boost';
// GOOD - Tree-shakeable imports
import { PrivacyBoost, PrivacyBoostError } from '@sunnyside-io/privacy-boost';
Analyze Bundle
# Webpack
npx webpack-bundle-analyzer stats.json
# Vite
npx vite-bundle-visualizer
Track Operation Duration
async function timedOperation<T>(
name: string,
operation: () => Promise<T>
): Promise<T> {
const start = performance.now();
try {
return await operation();
} finally {
const duration = performance.now() - start;
console.log(`${name}: ${duration.toFixed(2)}ms`);
// Send to analytics
if (duration > 5000) {
trackSlowOperation(name, duration);
}
}
}
// Usage
const result = await timedOperation('deposit', () =>
sdk.vault.shield(params)
);
Use React DevTools Profiler to identify slow renders.
Best Practices Summary
- Lazy load WASM - Don’t block initial page load
- Use cache wisely - Balance freshness vs performance
- Select specific state - Avoid unnecessary re-renders
- Batch operations - Reduce network requests
- Memoize calculations - Avoid redundant work
- Clean up subscriptions - Prevent memory leaks
- Monitor performance - Track slow operations
Next Steps