Performance Monitoring
Performance monitoring utilities are exported from rn-iconify/dev to keep production bundles lean.
Monitor and optimize icon loading performance in your app with built-in metrics collection.
Enable Monitoringโ
Enable performance monitoring in development:
import { enablePerformanceMonitoring, getPerformanceReport } from 'rn-iconify/dev';
// Enable monitoring
enablePerformanceMonitoring();
// Later, retrieve the report
const report = getPerformanceReport();
console.log(`Cache hit rate: ${(report.cacheStats.hitRate * 100).toFixed(1)}%`);
console.log(`Avg load time: ${report.summary.avgLoadTime.toFixed(2)}ms`);
Performance Reportโ
The report object contains comprehensive metrics:
interface PerformanceReport {
summary: {
avgLoadTime: number;
minLoadTime: number;
maxLoadTime: number;
p50LoadTime: number;
p90LoadTime: number;
p99LoadTime: number;
totalLoads: number;
totalErrors: number;
uptime: number;
};
cacheStats: {
memoryHits: number;
bundledHits: number;
diskHits: number;
networkFetches: number;
errors: number;
totalRequests: number;
hitRate: number;
};
loadTimesByType: {
memory: number;
bundled: number;
disk: number;
network: number;
};
slowestIcons: Array<{
iconName: string;
avgDuration: number;
count: number;
}>;
mostUsedIcons: Array<{
iconName: string;
count: number;
}>;
/** Recent load events (last 100) */
recentEvents: IconLoadEvent[];
/** Report generation timestamp */
generatedAt: number;
}
Usage Exampleโ
import { useEffect } from 'react';
import { enablePerformanceMonitoring, getPerformanceReport, PerformanceMonitor } from 'rn-iconify/dev';
function App() {
useEffect(() => {
// Enable in development only
if (__DEV__) {
enablePerformanceMonitoring();
}
// Log metrics periodically
const interval = setInterval(() => {
const report = getPerformanceReport();
console.log('Icon Performance:', {
loaded: report.summary.totalLoads,
cacheHitRate: `${(report.cacheStats.hitRate * 100).toFixed(1)}%`,
avgLoadTime: `${report.summary.avgLoadTime.toFixed(0)}ms`,
errors: report.summary.totalErrors,
});
}, 10000);
return () => clearInterval(interval);
}, []);
return <MainApp />;
}
Debug Componentโ
Create a debug overlay for development:
import { useState, useEffect } from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { enablePerformanceMonitoring, getPerformanceReport } from 'rn-iconify/dev';
function IconDebugOverlay() {
const [report, setReport] = useState(getPerformanceReport());
useEffect(() => {
enablePerformanceMonitoring();
const interval = setInterval(() => {
setReport(getPerformanceReport());
}, 1000);
return () => clearInterval(interval);
}, []);
if (!__DEV__) return null;
return (
<View style={styles.overlay}>
<Text style={styles.title}>Icon Metrics</Text>
<Text style={styles.metric}>
Loaded: {report.summary.totalLoads}
</Text>
<Text style={styles.metric}>
Cache: {(report.cacheStats.hitRate * 100).toFixed(0)}%
</Text>
<Text style={styles.metric}>
Avg: {report.summary.avgLoadTime.toFixed(0)}ms
</Text>
<Text style={styles.metric}>
Errors: {report.summary.totalErrors}
</Text>
</View>
);
}
const styles = StyleSheet.create({
overlay: {
position: 'absolute',
top: 50,
right: 10,
backgroundColor: 'rgba(0,0,0,0.8)',
padding: 10,
borderRadius: 8,
zIndex: 9999,
},
title: {
color: 'white',
fontWeight: 'bold',
marginBottom: 5,
},
metric: {
color: 'white',
fontSize: 12,
},
});
Bundle Statisticsโ
Analyze bundle statistics:
import { loadOfflineBundle, getBundleStats } from 'rn-iconify';
import iconBundle from './assets/icons.bundle.json';
// Get statistics from bundle before loading
const stats = getBundleStats(iconBundle);
console.log('Bundle stats:', {
totalIcons: stats.iconCount,
prefixes: stats.prefixes,
sizeKB: (stats.estimatedSizeBytes / 1024).toFixed(2),
generatedAt: stats.generatedAt,
});
// Load the bundle
loadOfflineBundle(iconBundle);
Identify Slow Iconsโ
Find icons that are slow to load:
import { getPerformanceReport } from 'rn-iconify/dev';
function analyzeSlowIcons() {
const report = getPerformanceReport();
// Get slowest icons from the report
const slowIcons = report.slowestIcons.filter(icon => icon.avgDuration > 500);
if (slowIcons.length > 0) {
console.warn('Slow loading icons:', slowIcons);
}
return slowIcons;
}
Subscribe to Eventsโ
Listen for icon load events in real-time:
import { PerformanceMonitor, enablePerformanceMonitoring } from 'rn-iconify/dev';
// Enable monitoring first
enablePerformanceMonitoring();
// Subscribe to events
const unsubscribe = PerformanceMonitor.subscribe((event) => {
if (event.type === 'error') {
console.error(`Failed to load icon: ${event.iconName}`, event.error);
} else if (event.duration > 500) {
console.warn(`Slow icon: ${event.iconName} took ${event.duration}ms`);
}
});
// Unsubscribe when done
unsubscribe();
Print Reportโ
Print a formatted report to the console:
import { printPerformanceReport, enablePerformanceMonitoring } from 'rn-iconify/dev';
// Enable and later print
enablePerformanceMonitoring();
// After some time, print formatted report
printPerformanceReport();
Output:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ rn-iconify Performance Report โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ Total Loads: 150 โ Errors: 0 โ
โ Cache Hit Rate: 94.7% โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ Load Times โ
โ Average: 12.34ms โ
โ Min: 0.12ms โ Max: 234.56ms โ
โ P50: 8.00ms โ P90: 45.00ms โ P99: 120.00ms โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ By Source โ
โ Memory: 0.15ms (89 hits) โ
โ Bundled: 0.10ms (42 hits) โ
โ Disk: 1.20ms (11 hits) โ
โ Network: 156.00ms (8 fetches) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Reset Monitoringโ
Clear all performance data:
import { PerformanceMonitor, getPerformanceReport } from 'rn-iconify/dev';
// Reset all metrics
PerformanceMonitor.reset();
// Metrics are now zeroed
const report = getPerformanceReport();
console.log(report.summary.totalLoads); // 0
Optimization Recommendationsโ
Based on metrics, optimize your icon usage:
High Network Fetchesโ
If networkFetches is high, consider:
import { prefetchIcons } from 'rn-iconify';
// Prefetch commonly used icons at app start
async function initApp() {
await prefetchIcons([
'mdi:home',
'mdi:settings',
'mdi:account',
// ... frequently used icons
]);
}
Low Cache Hit Rateโ
If hitRate is low:
- Check cache configuration:
import { configure } from 'rn-iconify';
configure({
cache: {
maxMemoryItems: 1000, // Increase max cached icons
enableDiskCache: true,
},
});
- Use Babel plugin for critical icons:
// babel.config.js
module.exports = {
plugins: [
['rn-iconify/babel', {
include: ['mdi:home', 'mdi:settings'],
}],
],
};
High Average Load Timeโ
If avgLoadTime is high:
- Use local Iconify server:
import { configure } from 'rn-iconify';
configure({
api: {
apiUrl: 'http://localhost:3000',
},
});
- Bundle critical icons:
// babel.config.js
module.exports = {
plugins: [
['rn-iconify/babel', {
include: ['mdi:*'], // Bundle all MDI icons
}],
],
};
Performance Targetsโ
Recommended targets for good icon performance:
| Metric | Target | Action if Poor |
|---|---|---|
| Cache Hit Rate | > 90% | Increase cache size, prefetch icons |
| Avg Load Time | < 100ms | Use local server, bundle critical icons |
| Errors | 0 | Check network, validate icon names |
Best Practicesโ
1. Development Onlyโ
if (__DEV__) {
enablePerformanceMonitoring();
}
2. Regular Monitoringโ
useEffect(() => {
const interval = setInterval(() => {
const report = getPerformanceReport();
// Analyze and log
}, 5000);
return () => clearInterval(interval);
}, []);
3. Set Performance Budgetโ
function checkIconBudget() {
const report = getPerformanceReport();
if (report.summary.avgLoadTime > 200) {
console.warn('Icon load time exceeds budget');
}
if (report.cacheStats.hitRate < 0.8) {
console.warn('Cache hit rate below target');
}
}
Disable Monitoringโ
Disable when not needed:
import { disablePerformanceMonitoring } from 'rn-iconify/dev';
disablePerformanceMonitoring();
PerformanceMonitor APIโ
The PerformanceMonitor object provides detailed access to performance data.
getSummaryโ
Get performance summary with percentiles:
import { PerformanceMonitor } from 'rn-iconify/dev';
const summary = PerformanceMonitor.getSummary();
console.log({
totalLoads: summary.totalLoads,
avgLoadTime: summary.avgLoadTime,
p50: summary.p50LoadTime, // median
p90: summary.p90LoadTime, // 90th percentile
p99: summary.p99LoadTime, // 99th percentile
totalErrors: summary.totalErrors,
uptime: summary.uptime,
});
getEventsโ
Get all recorded load events:
import { PerformanceMonitor } from 'rn-iconify/dev';
const events = PerformanceMonitor.getEvents();
events.forEach(event => {
console.log({
icon: event.iconName,
duration: event.duration,
type: event.type, // 'memory_hit' | 'bundled_hit' | 'disk_hit' | 'network_fetch' | 'error'
timestamp: event.timestamp,
error: event.error, // Only present if type is 'error'
});
});
getCacheStatsโ
Get cache-specific statistics:
import { PerformanceMonitor } from 'rn-iconify/dev';
const stats = PerformanceMonitor.getCacheStats();
console.log({
memoryHits: stats.memoryHits,
bundledHits: stats.bundledHits,
diskHits: stats.diskHits,
networkFetches: stats.networkFetches,
errors: stats.errors,
totalRequests: stats.totalRequests,
hitRate: stats.hitRate,
});
subscribeโ
Subscribe to real-time load events:
import { PerformanceMonitor } from 'rn-iconify/dev';
const unsubscribe = PerformanceMonitor.subscribe((event) => {
// Called for every icon load
console.log(`${event.iconName}: ${event.duration}ms from ${event.type}`);
if (event.type === 'error') {
console.error(`Failed to load ${event.iconName}:`, event.error);
}
});
// Cleanup
return () => unsubscribe();
isEnabledโ
Check if monitoring is enabled:
import { PerformanceMonitor } from 'rn-iconify/dev';
if (PerformanceMonitor.isEnabled()) {
console.log('Performance monitoring is active');
}
Next Stepsโ
- Babel Plugin - Bundle icons for 0ms load
- Architecture - Understanding the caching system
- Custom Server - Self-hosted Iconify server