Performance Best Practices
Optimize your Resync integration for the best performance.
SDK Initialization
Initialize Early
Initialize Resync as early as possible in your app lifecycle:
// ✅ Good - Initialize at app startup
import Resync from 'resync-javascript';
async function initApp() {
await Resync.init({
key: process.env.RESYNC_API_KEY,
appId: 7,
storage: localStorage,
environment: 'production',
});
// Then load your app
startApp();
}
initApp();
// ❌ Bad - Lazy initialization
function SomeComponent() {
useEffect(() => {
Resync.init({ /* config */ }); // Too late!
}, []);
}
Caching Strategy
Use Production Mode
Set environment: 'production' for optimal caching:
Resync.init({
// ...
environment: 'production', // 6-hour cache
});
Cache TTL by environment:
- Production: 6 hours (optimal for live apps)
- Sandbox: 0 (no caching, for development)
Preload Content
Fetch content before it's needed:
// Prefetch on app load
useEffect(() => {
const contentViews = Resync.getContent();
// Content is now cached
}, []);
// Later, instant access
function MyComponent() {
const contentViews = Resync.getContent(); // From cache!
}
Event Tracking
Batch Events
Don't log events in tight loops:
// ❌ Bad
items.forEach(item => {
Resync.logEvent({ eventId: 'item_viewed', metadata: { item } });
});
// ✅ Good
Resync.logEvent({
eventId: 'items_viewed',
metadata: { itemCount: items.length, items: items.map(i => i.id) },
});
Debounce Frequent Events
import { debounce } from 'lodash';
const trackScroll = debounce(() => {
Resync.logEvent({ eventId: 'screen_scrolled' });
}, 1000);
window.addEventListener('scroll', trackScroll);
React Native Optimization
Avoid Unnecessary Re-renders
// ✅ Good - Memoize navigation/function registries
const navigationRegistry = useMemo(() => ({
navigate: navigation.navigate,
goBack: navigation.goBack,
}), [navigation]);
const functionRegistry = useMemo(() => ({
handleSubmit: async (data) => {
await submitForm(data);
},
}), []);
<ResyncContentView
name="Form"
navigationRegistry={navigationRegistry}
functionRegistry={functionRegistry}
/>
Use Loading States
const [loading, setLoading] = useState(true);
useEffect(() => {
initResync();
}, []);
const initResync = async () => {
await Resync.init({ /* config */ });
setLoading(false);
};
if (loading) {
return <LoadingScreen />;
}
return <App />;
Image Optimization
For content with images, optimize image sizes:
- Use appropriate dimensions (max 2x device width)
- Use modern formats (WebP, AVIF)
- Implement lazy loading
- Use CDN for image hosting
Network Optimization
Minimize API Calls
// ❌ Bad - Multiple calls
const config1 = Resync.getConfig('KEY1');
const config2 = Resync.getConfig('KEY2');
const config3 = Resync.getConfig('KEY3');
// ✅ Good - Single initialization, multiple reads
await Resync.init({ /* config */ }); // One network call
// Then read from cache
const config1 = Resync.getConfig('KEY1');
const config2 = Resync.getConfig('KEY2');
const config3 = Resync.getConfig('KEY3');
Memory Management
Clean Up Subscriptions
useEffect(() => {
const callback = (config) => {
console.log('Config updated:', config);
};
Resync.subscribe(callback);
// ✅ Clean up on unmount
return () => {
Resync.unsubscribe(callback);
};
}, []);
Monitoring
Track Performance Metrics
// Track initialization time
const startTime = Date.now();
await Resync.init({ /* config */ });
const duration = Date.now() - startTime;
console.log('Resync init time:', duration, 'ms');
// Log to analytics
analytics.track('resync_init_duration', { duration });
Benchmarks
Typical performance metrics:
| Operation | Time | Notes |
|---|---|---|
| SDK initialization | 50-200ms | First time (network) |
| SDK initialization | < 10ms | Cached |
| getConfig() | < 1ms | Always from memory |
| getContent() | < 1ms | Always from memory |
| getVariant() | 10-50ms | Network call |
| logEvent() | 5-20ms | Async, non-blocking |