Performance Monitoring & Optimization
Relevant source files
The following files were used as context for generating this wiki page:The project incorporates a multi-faceted approach to performance monitoring and optimization, primarily active during development (__DEV__). The system is built around two main pillars: a comprehensive PerformanceService for detailed metric collection and a suite of utilities in performance.js for granular control and proactive optimization. These tools enable developers to track screen transitions, API calls, component render times, and manage resource-intensive operations efficiently.
The strategy also includes a structured logging service that is automatically disabled in production to prevent performance overhead. Furthermore, the application can adapt its features based on device capabilities, ensuring a smoother experience on low-end hardware.
Sources: src/services/performanceService.js, src/core/utils/performance.js, src/core/utils/logger.js
Core Monitoring Services
The application utilizes two primary classes for performance measurement, each serving a different level of granularity.
PerformanceService
This is a singleton service dedicated to collecting and aggregating detailed performance metrics throughout the application's lifecycle. It automatically starts monitoring in development mode and logs periodic reports.
Sources: src/services/performanceService.js:8-323
The diagram below shows the structure of the PerformanceService class.
Key Methods
| Method | Description |
|---|---|
mark(name) | Sets a timestamped marker to denote the start of an operation. |
measure(name, startMark, endMark) | Calculates the duration between two marks or a start mark and the current time. |
trackScreenTransition(...) | Measures and aggregates screen transition times. Warns if a transition exceeds 1000ms. |
trackApiCall(...) | Tracks the duration and success/failure of API calls. Warns if a call exceeds 3000ms. |
trackRender(...) | Tracks component render times. Warns if a render exceeds 100ms. |
logReport() | Logs a summary and detailed breakdown of all collected metrics to the console. |
startMonitoring() | Starts an interval timer (60 seconds) to automatically log performance reports in development. |
Sources: src/services/performanceService.js:19-312
Data Structure
The service stores all collected data in the metrics property, which is structured to categorize different types of measurements.
this.metrics = {
screenTransitions: {},
apiCalls: {},
renders: {},
memory: [],
};
Sources: src/services/performanceService.js:10-15
PerformanceMonitor
A lighter-weight utility class for simple, ad-hoc task timing. It uses the standard performance.now() API and is also enabled only in development.
Sources: src/core/utils/performance.js:9-62
Key Methods
| Method | Description |
|---|---|
start(label) | Starts timing a task with a given label. |
end(label) | Ends timing a task and logs the duration to the console. |
getAll() | Returns an array of all recorded metrics. |
Sources: src/core/utils/performance.js:16-52
Implementation and Usage
Performance tracking is integrated into the application via HOCs, hooks, and direct service calls.
Component Render Tracking
Component render times can be automatically tracked using the withPerformanceTracking Higher-Order Component (HOC).
// src/services/performanceService.js:328-339
export const withPerformanceTracking = (Component, componentName) => {
return (props) => {
const startTime = Date.now();
React.useEffect(() => {
const renderTime = Date.now() - startTime;
performanceService.trackRender(componentName || Component.name, renderTime);
});
return <Component {...props} />;
};
};
Sources: src/services/performanceService.js:328-339
Custom Measurement with Hooks
The usePerformance hook provides a simple way to measure the duration a component is mounted.
// src/services/performanceService.js:344-352
export const usePerformance = (name) => {
React.useEffect(() => {
performanceService.mark(`${name}_start`);
return () => {
performanceService.measure(name, `${name}_start`);
};
}, [name]);
};
Sources: src/services/performanceService.js:344-352
Manual Measurement Flow
For custom operations, developers can use mark() and measure() to get precise timings.
This sequence diagram illustrates a typical manual measurement flow.
Optimization Utilities
The file src/core/utils/performance.js contains several helper functions and classes for proactive performance optimization.
| Utility | Description | Source File |
|---|---|---|
debounce(func, wait) | Delays function execution until after a certain time has passed without it being called. | src/core/utils/performance.js:70-80 |
throttle(func, limit) | Ensures a function is only executed once per specified time limit. | src/core/utils/performance.js:85-94 |
raf(callback) | A cross-platform wrapper for requestAnimationFrame. | src/core/utils/performance.js:99-105 |
isLowEndDevice() | (Web only) Detects if the device has low CPU cores or memory. | src/core/utils/performance.js:200-207 |
getOptimalSettings() | Returns a configuration object with settings adjusted for low-end or high-end devices. | src/core/utils/performance.js:212-223 |
AssetPreloader | A class to preload assets like images and models to prevent loading jank during runtime. | src/core/utils/performance.js:228-292 |
Device-Based Optimization
The application can adjust its graphical settings based on the detected hardware capabilities using isLowEndDevice and getOptimalSettings.
This flowchart shows the logic for determining optimal settings.
The settings returned by getOptimalSettings are used to configure the 3D engine for better performance on less powerful devices.
Sources: src/core/utils/constants.js:71-80, src/core/utils/performance.js:212-223
Asset Preloading
The AssetPreloader class provides a mechanism to load assets before they are needed, improving user experience by reducing wait times.
This flowchart illustrates the asset preloading logic.
Structured Logging
A dedicated logger.js service provides structured, level-based logging that is automatically disabled in production builds to avoid performance degradation. This is a key performance practice, as it prevents console.log statements from impacting the production environment.
The logger supports different levels (DEBUG, INFO, WARN, ERROR), timestamps, and context objects.
import logger from './src/core/utils/logger';
// Basic logging
logger.info('User logged in', { userId: 123 });
// Timing
logger.time('API Call');
await fetchData();
logger.timeEnd('API Call');
Sources: SECURITY_AND_CLEANUP_FIXES.md, src/core/utils/logger.js
Summary
The performance monitoring and optimization framework in this project is robust and developer-centric. It provides detailed insights during development through PerformanceService and PerformanceMonitor without impacting production performance. Proactive optimization is achieved through utilities for debouncing, throttling, asset preloading, and adaptive settings for different hardware profiles. The inclusion of a production-safe logger further solidifies the commitment to a performant end-user experience.