Skip to content

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 length
  • batch_send_duration: Time to send batch
  • memory_usage: SDK memory consumption
  • event_drop_rate: Percentage of dropped events
  • network_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:

  1. Check batch size: Reduce if queue grows too large
  2. Property size: Avoid large string properties
  3. Event frequency: Implement client-side sampling
  4. Memory leaks: Ensure proper cleanup in SPAs

Slow Event Processing:

  1. Network latency: Check batch size and flush interval
  2. Property validation: Pre-validate properties
  3. Synchronous calls: Ensure async tracking
  4. Debug mode: Disable in production

High CPU Usage:

  1. Event frequency: Implement debouncing
  2. Property processing: Simplify event properties
  3. Background processing: Move to worker threads
  4. 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


Performance questions? Contact our team for optimization guidance.