Performance Optimization
Learn how to optimize performance when using Flowfull Clients.
SWR Configuration
Global Configuration
Configure SWR globally for optimal performance:
typescript
import { SWRConfig } from 'swr';
import { PubflowProvider } from '@pubflow/react';
function App() {
return (
<PubflowProvider config={{ baseUrl: 'https://api.example.com' }}>
<SWRConfig
value={{
revalidateOnFocus: false,
revalidateOnReconnect: true,
dedupingInterval: 60000, // 1 minute
focusThrottleInterval: 5000, // 5 seconds
errorRetryCount: 3,
errorRetryInterval: 5000,
}}
>
<YourApp />
</SWRConfig>
</PubflowProvider>
);
}Per-Query Configuration
Optimize individual queries:
typescript
import { useBridgeApi, useBridgeQuery } from '@pubflow/react';
function UserList() {
const userService = useBridgeApi({ endpoint: 'users' });
const { data } = useBridgeQuery(
userService,
'list',
{ limit: 20 },
{
// Refresh every 30 seconds
refreshInterval: 30000,
// Don't revalidate on focus
revalidateOnFocus: false,
// Keep previous data while revalidating
keepPreviousData: true,
}
);
return <div>{/* ... */}</div>;
}Caching Strategies
Persistent Cache
Enable persistent caching in React:
typescript
import { PubflowProvider } from '@pubflow/react';
function App() {
return (
<PubflowProvider
config={{ baseUrl: 'https://api.example.com' }}
persistentCache={{
enabled: true,
maxAge: 3600000, // 1 hour
}}
>
<YourApp />
</PubflowProvider>
);
}Cache Invalidation
Manually invalidate cache when needed:
typescript
import { useBridgeApi, useBridgeMutation } from '@pubflow/react';
import { mutate } from 'swr';
function CreateUser() {
const userService = useBridgeApi({ endpoint: 'users' });
const { mutate: createUser } = useBridgeMutation(userService, 'create');
async function handleCreate(data: any) {
await createUser({ data });
// Invalidate users list cache
mutate('/bridge/users');
}
return <div>{/* ... */}</div>;
}Pagination Optimization
Infinite Scroll
Implement efficient infinite scroll:
typescript
import { useState, useEffect } from 'react';
import { useBridgeApi, useBridgeQuery } from '@pubflow/react';
function InfiniteUserList() {
const [page, setPage] = useState(1);
const [allUsers, setAllUsers] = useState<any[]>([]);
const userService = useBridgeApi({ endpoint: 'users' });
const { data, meta } = useBridgeQuery(
userService,
'list',
{ page, limit: 20 }
);
useEffect(() => {
if (data) {
setAllUsers(prev => [...prev, ...data]);
}
}, [data]);
function loadMore() {
if (meta?.hasMore) {
setPage(p => p + 1);
}
}
return (
<div>
{allUsers.map(user => (
<div key={user.id}>{user.name}</div>
))}
{meta?.hasMore && (
<button onClick={loadMore}>Load More</button>
)}
</div>
);
}Virtual Scrolling
Use virtual scrolling for large lists:
typescript
import { FixedSizeList } from 'react-window';
import { useBridgeApi, useBridgeQuery } from '@pubflow/react';
function VirtualUserList() {
const userService = useBridgeApi({ endpoint: 'users' });
const { data } = useBridgeQuery(
userService,
'list',
{ limit: 1000 }
);
const Row = ({ index, style }: any) => (
<div style={style}>
{data?.[index]?.name}
</div>
);
return (
<FixedSizeList
height={600}
itemCount={data?.length || 0}
itemSize={50}
width="100%"
>
{Row}
</FixedSizeList>
);
}Request Optimization
Debouncing Search
Debounce search queries to reduce API calls:
typescript
import { useState, useEffect } from 'react';
import { useBridgeApi, useBridgeQuery } from '@pubflow/react';
function SearchUsers() {
const [query, setQuery] = useState('');
const [debouncedQuery, setDebouncedQuery] = useState('');
const userService = useBridgeApi({ endpoint: 'users' });
// Debounce search query
useEffect(() => {
const timer = setTimeout(() => {
setDebouncedQuery(query);
}, 300);
return () => clearTimeout(timer);
}, [query]);
const { data } = useBridgeQuery(
userService,
'search',
{ q: debouncedQuery, limit: 10 },
{
// Only fetch if query is not empty
isPaused: () => !debouncedQuery
}
);
return (
<div>
<input
value={query}
onChange={(e) => setQuery(e.target.value)}
placeholder="Search..."
/>
{data?.map(user => (
<div key={user.id}>{user.name}</div>
))}
</div>
);
}Request Deduplication
SWR automatically deduplicates requests with the same key.
Memory Optimization
Cleanup on Unmount
Clean up resources when components unmount:
typescript
import { useEffect } from 'react';
import { useBridgeApi, useBridgeQuery } from '@pubflow/react';
function UserDetail({ userId }: any) {
const userService = useBridgeApi({ endpoint: 'users' });
const { data } = useBridgeQuery(
userService,
'get',
{ id: userId }
);
useEffect(() => {
return () => {
// Cleanup logic here
};
}, []);
return <div>{data?.name}</div>;
}Bundle Size Optimization
Tree Shaking
Import only what you need:
typescript
// ❌ Bad - imports everything
import * as Pubflow from '@pubflow/react';
// ✅ Good - imports only what's needed
import { useAuth, useBridgeApi, useBridgeQuery } from '@pubflow/react';Code Splitting
Split code by route:
typescript
import { lazy, Suspense } from 'react';
const Users = lazy(() => import('./pages/Users'));
const Dashboard = lazy(() => import('./pages/Dashboard'));
function App() {
return (
<Suspense fallback={<div>Loading...</div>}>
<Routes>
<Route path="/users" element={<Users />} />
<Route path="/dashboard" element={<Dashboard />} />
</Routes>
</Suspense>
);
}Monitoring
Performance Metrics
Monitor query performance:
typescript
import { useBridgeApi, useBridgeQuery } from '@pubflow/react';
function UserList() {
const userService = useBridgeApi({ endpoint: 'users' });
const { data, isLoading } = useBridgeQuery(
userService,
'list',
{ limit: 20 },
{
onSuccess: (data) => {
console.log('Query succeeded:', data.length, 'items');
},
onError: (error) => {
console.error('Query failed:', error);
}
}
);
return <div>{/* ... */}</div>;
}Next Steps
- Custom Storage - Custom storage adapters
- Multi-Instance - Multi-instance configuration
- Offline Support - Offline functionality