Performance Impact
LoopKit is designed for minimal performance impact while providing maximum insights. Here's how to optimize your integration.
Performance Overview
Baseline Impact
Web Applications:
- Bundle Size: 15KB gzipped (JavaScript SDK)
- Memory Usage: <2MB typical usage
- CPU Impact: <1% on modern devices
- Network: Batched requests, ~100KB/day typical usage
Unity Games:
- Build Size: 200KB additional
- Runtime Memory: 512KB-2MB
- Frame Rate Impact: <0.1ms per frame
- GC Pressure: Minimal allocations
Performance Benchmarks
Event Tracking Latency:
- Local queuing: <1ms
- Batch processing: 5-30ms
- Network transmission: 50-200ms
- End-to-end: <250ms
Throughput Limits:
- Events/second: 10,000+ per client
- Concurrent users: Unlimited
- API rate limits: 10,000 events/minute
- Batch size: 100 events maximum
SDK Performance Characteristics
Web SDK (@loopkit/react)
React Provider Performance:
jsx
import { LoopKitProvider } from '@loopkit/react';
// Optimized configuration
<LoopKitProvider
apiKey="your-api-key"
options={{
batchSize: 50, // Balance latency vs overhead
flushInterval: 30, // Seconds, reduce for real-time needs
debug: false, // Disable in production
enableAutoCapture: false, // Disable if not needed
}}
>
<App />
</LoopKitProvider>;
Event Tracking Performance:
javascript
// Fast: Synchronous queuing
track('user_action', { feature: 'search' });
// Faster: Batch multiple events
const events = [
{ name: 'page_view', properties: { page: '/dashboard' } },
{ name: 'feature_used', properties: { feature: 'export' } },
{ name: 'button_click', properties: { button: 'download' } },
];
trackBatch(events);
// Fastest: Pre-validate properties
const validatedProperties = validateProperties({
user_id: '123',
session_time: 180,
});
track('session_end', validatedProperties);
Unity SDK Performance
Memory-Optimized Tracking:
csharp
using LoopKit;
// Efficient object reuse
private readonly Dictionary<string, object> _eventProps =
new Dictionary<string, object>();
void TrackLevelComplete(int level, int score) {
_eventProps.Clear();
_eventProps["level"] = level;
_eventProps["score"] = score;
_eventProps["timestamp"] = Time.time;
LoopKit.Track("level_completed", _eventProps);
}
// Batch tracking for high-frequency events
private readonly List<TrackingEvent> _eventBatch =
new List<TrackingEvent>();
void Update() {
// Collect events during frame
if (shouldTrackMovement) {
_eventBatch.Add(new TrackingEvent("player_moved",
new { x = transform.position.x, y = transform.position.y }));
}
// Flush at end of frame
if (_eventBatch.Count > 0) {
LoopKit.TrackBatch(_eventBatch);
_eventBatch.Clear();
}
}
Optimization Strategies
1. Batch Configuration
Optimize for Your Use Case:
javascript
// High-frequency app (gaming, real-time)
const highFrequencyConfig = {
batchSize: 100, // Larger batches
flushInterval: 60, // Less frequent flushes
enableDebounce: true, // Reduce duplicate events
};
// Low-frequency app (SaaS, content)
const lowFrequencyConfig = {
batchSize: 10, // Smaller batches
flushInterval: 15, // More frequent flushes
enableDebounce: false, // Track all events
};
// Real-time requirements
const realTimeConfig = {
batchSize: 1, // Immediate sending
flushInterval: 1, // Very frequent
enableCompression: true, // Reduce bandwidth
};
2. Event Filtering
Client-Side Filtering:
javascript
// Filter events before tracking
const shouldTrack = (eventName, properties) => {
// Skip debug events in production
if (eventName.startsWith('debug_') && !DEBUG_MODE) {
return false;
}
// Skip high-frequency events for free users
if (HIGH_FREQUENCY_EVENTS.includes(eventName) && !isPremiumUser()) {
return false;
}
// Skip events with invalid data
if (!properties || Object.keys(properties).length === 0) {
return false;
}
return true;
};
const track = (eventName, properties) => {
if (shouldTrack(eventName, properties)) {
LoopKit.track(eventName, properties);
}
};
3. Property Optimization
Efficient Property Handling:
javascript
// ❌ Expensive: Complex objects
track('user_action', {
user: { profile: { settings: { theme: 'dark' } } }, // Nested
metadata: new Date(), // Complex types
arrayData: [1, 2, 3, 4, 5], // Arrays
});
// ✅ Efficient: Flat, simple properties
track('user_action', {
user_theme: 'dark', // Flattened
timestamp: Date.now(), // Simple type
item_count: 5, // Aggregated
});
// Property validation and cleanup
const cleanProperties = (props) => {
const cleaned = {};
for (const [key, value] of Object.entries(props)) {
// Skip null/undefined
if (value == null) continue;
// Convert to string if needed
if (typeof value === 'object') {
cleaned[key] = JSON.stringify(value);
} else {
cleaned[key] = value;
}
}
return cleaned;
};
4. Memory Management
Prevent Memory Leaks:
javascript
// React: Proper cleanup
const MyComponent = () => {
const { track } = useLoopKit();
useEffect(() => {
// Component mount tracking
track('component_mounted', { component: 'MyComponent' });
return () => {
// Component unmount tracking
track('component_unmounted', { component: 'MyComponent' });
};
}, [track]);
// Use useCallback for event handlers
const handleClick = useCallback(() => {
track('button_clicked', { button: 'action' });
}, [track]);
return <button onClick={handleClick}>Action</button>;
};
// Unity: Manual cleanup
public class GameAnalytics : MonoBehaviour {
private void OnDestroy() {
// Clean up any pending events
LoopKit.Flush();
}
private void OnApplicationPause(bool pauseStatus) {
if (pauseStatus) {
// Flush events when app is paused
LoopKit.Flush();
}
}
}
Performance Monitoring
1. Built-in Metrics
SDK Performance Monitoring:
javascript
// Enable performance monitoring
<LoopKitProvider
options={{
debug: true,
enablePerformanceMonitoring: true,
onPerformanceMetric: (metric) => {
console.log('LoopKit Performance:', metric);
// Alert on performance issues
if (metric.type === 'batch_send_duration' && metric.value > 1000) {
console.warn('Slow batch send detected:', metric.value, 'ms');
}
},
}}
/>
Performance Metrics Available:
event_queue_size
: Current queue lengthbatch_send_duration
: Time to send batchmemory_usage
: SDK memory consumptionevent_drop_rate
: Percentage of dropped eventsnetwork_error_rate
: Failed request percentage
2. Custom Performance Tracking
Track Your Own Performance:
javascript
// Measure feature performance
const measureFeaturePerformance = async (featureName, fn) => {
const startTime = performance.now();
try {
const result = await fn();
const duration = performance.now() - startTime;
track('feature_performance', {
feature: featureName,
duration: Math.round(duration),
success: true,
});
return result;
} catch (error) {
const duration = performance.now() - startTime;
track('feature_performance', {
feature: featureName,
duration: Math.round(duration),
success: false,
error: error.message,
});
throw error;
}
};
// Usage
const handleExport = async () => {
await measureFeaturePerformance('data_export', async () => {
const data = await exportData();
return data;
});
};
3. Performance Alerts
Set Up Monitoring:
javascript
// Performance threshold monitoring
const PERFORMANCE_THRESHOLDS = {
batch_send_duration: 2000, // 2 seconds
memory_usage: 5 * 1024 * 1024, // 5MB
queue_size: 1000, // 1000 events
error_rate: 0.05, // 5%
};
const monitorPerformance = (metric) => {
const threshold = PERFORMANCE_THRESHOLDS[metric.type];
if (threshold && metric.value > threshold) {
// Send alert to monitoring system
track('performance_alert', {
metric_type: metric.type,
metric_value: metric.value,
threshold: threshold,
severity: 'warning',
});
// Log for debugging
console.warn(`LoopKit performance issue: ${metric.type} = ${metric.value}`);
}
};
Network Optimization
1. Request Optimization
Compression and Batching:
javascript
// Configure optimal networking
<LoopKitProvider
options={{
enableCompression: true, // Gzip compression
batchSize: 50, // Optimal batch size
retryConfig: {
maxRetries: 3,
backoffMultiplier: 2,
maxBackoffDelay: 30000,
},
requestTimeout: 10000, // 10 second timeout
}}
/>
2. Offline Handling
Robust Offline Support:
javascript
// Handle network connectivity
const handleNetworkChange = () => {
if (navigator.onLine) {
// Network restored - flush pending events
LoopKit.flush();
track('network_restored');
} else {
// Network lost - events will queue locally
track('network_lost');
}
};
window.addEventListener('online', handleNetworkChange);
window.addEventListener('offline', handleNetworkChange);
// Unity offline handling
public class NetworkManager : MonoBehaviour {
private void Update() {
if (Application.internetReachability == NetworkReachability.NotReachable) {
// Events will queue automatically
LoopKit.SetOfflineMode(true);
} else {
LoopKit.SetOfflineMode(false);
}
}
}
Performance Best Practices
1. Event Design
Efficient Event Structure:
javascript
// ❌ Inefficient
track('user_interaction', {
timestamp: new Date().toISOString(),
user_agent: navigator.userAgent,
url: window.location.href,
referrer: document.referrer,
screen_width: screen.width,
screen_height: screen.height,
// ... 20 more properties
});
// ✅ Efficient
track('button_click', {
button: 'export',
section: 'dashboard',
});
// Use system properties for device info
track(
'session_start',
{
session_id: generateSessionId(),
},
{
// System properties added automatically
platform: 'web',
device_type: 'desktop',
}
);
2. Integration Patterns
Lazy Loading:
javascript
// Lazy load LoopKit for performance
const loadAnalytics = async () => {
if (typeof window !== 'undefined' && !window.analyticsLoaded) {
const { LoopKit } = await import('@loopkit/javascript');
LoopKit.init('your-api-key');
window.analyticsLoaded = true;
}
};
// Load after critical path
useEffect(() => {
const timer = setTimeout(loadAnalytics, 2000);
return () => clearTimeout(timer);
}, []);
3. Development vs Production
Environment-Specific Configuration:
javascript
const config = {
apiKey: process.env.REACT_APP_LOOPKIT_API_KEY,
debug: process.env.NODE_ENV === 'development',
batchSize: process.env.NODE_ENV === 'production' ? 50 : 1,
flushInterval: process.env.NODE_ENV === 'production' ? 30 : 5,
enablePerformanceMonitoring: process.env.NODE_ENV === 'development',
};
<LoopKitProvider options={config}>
<App />
</LoopKitProvider>;
Troubleshooting Performance Issues
Common Issues & Solutions
High Memory Usage:
- Check batch size: Reduce if queue grows too large
- Property size: Avoid large string properties
- Event frequency: Implement client-side sampling
- Memory leaks: Ensure proper cleanup in SPAs
Slow Event Processing:
- Network latency: Check batch size and flush interval
- Property validation: Pre-validate properties
- Synchronous calls: Ensure async tracking
- Debug mode: Disable in production
High CPU Usage:
- Event frequency: Implement debouncing
- Property processing: Simplify event properties
- Background processing: Move to worker threads
- Platform issues: Check platform-specific optimizations
Performance Debugging
Enable Debug Mode:
javascript
// Detailed performance logging
<LoopKitProvider
options={{
debug: true,
logLevel: 'verbose',
enableTimings: true,
}}
/>;
// Monitor specific metrics
const debugPerformance = () => {
console.log('Queue size:', LoopKit.getQueueSize());
console.log('Memory usage:', LoopKit.getMemoryUsage());
console.log('Network stats:', LoopKit.getNetworkStats());
};
// Run periodically in development
if (process.env.NODE_ENV === 'development') {
setInterval(debugPerformance, 10000);
}
Next Steps
- Review troubleshooting guide →
- Learn about data retention →
- Explore privacy settings →
- Join performance discussions →
Performance questions? Contact our team for optimization guidance.