# Performance Monitoring `mancha` includes built-in performance monitoring tools to help you identify and optimize slow renders. These tools are designed to have minimal overhead when disabled and provide detailed insights when enabled. ## Debug Levels Performance monitoring is controlled through debug levels. The `debug()` method accepts either a boolean (for backwards compatibility) or a debug level string: ```js const { $ } = Mancha; // Enable lifecycle-level debugging (recommended for most use cases) $.debug(true); // Same as $.debug('lifecycle') $.debug('lifecycle'); // Enable effect-level debugging (logs individual effect timings) $.debug('effects'); // Enable verbose debugging (logs everything, including internal operations) $.debug('verbose'); // Disable debugging $.debug(false); // Same as $.debug('off') $.debug('off'); ``` ### Debug Level Behavior | Level | Tracking | Console Output | |------------|-----------------------------|-----------------------------------------| | `off` | Nothing | None | | `lifecycle`| Lifecycle + effect stats | Slow effects only (>16ms) | | `effects` | Same as lifecycle | Above + individual effect timings | | `verbose` | Same as lifecycle | Above + all internal logging | The `lifecycle` level is the recommended default for performance analysis. It tracks all the data needed for `getPerformanceReport()` while keeping console output minimal. ## Performance Reports After mounting your application with debugging enabled, you can retrieve a structured performance report: ```js const { $ } = Mancha; $.debug('lifecycle'); await $.mount(document.body); const report = $.getPerformanceReport(); console.log(report); ``` ### Report Structure ```js { lifecycle: { mountTime: 45.2, // Total mount time in milliseconds preprocessTime: 12.1, // Time spent in preprocessing phase renderTime: 33.1 // Time spent in rendering phase }, effects: { total: 25, // Total number of unique effects byDirective: { 'bind': { count: 10, totalTime: 5.2 }, 'for': { count: 3, totalTime: 15.8 }, 'text': { count: 12, totalTime: 2.1 } }, slowest: [ // Top 10 slowest effects { id: 'for:product-list:products', executionCount: 1, totalTime: 15.8, avgTime: 15.8 }, // ... ] }, observers: { totalKeys: 8, // Number of unique keys being watched totalObservers: 25, // Total number of observers byKey: { // Observers per key 'products': 5, 'selectedItem': 3 } } } ``` ## Measuring Specific User Flows By default, performance data resets on each `mount()` call. To measure a specific user flow (like a button click or data update) after the initial mount, use `clearPerformanceReport()`: ```js const { $ } = Mancha; $.debug('lifecycle'); await $.mount(document.body); // Setup is complete. Now measure a specific user flow. $.clearPerformanceReport(); // Perform the user flow you want to measure. $.items = await fetchLargeDataset(); // Get the report for just this flow. const report = $.getPerformanceReport(); console.log('User flow effects:', report.effects.slowest); ``` This is useful for optimizing specific interactions without the noise of initial mount timing. ## Effect Identification Each effect is identified by a unique ID composed of the directive name, element identifier, and expression. The element identifier is determined by the following priority: 1. `data-perfid` - Explicit performance ID (highest priority) 2. `id` - Standard HTML id attribute 3. `data-testid` - Common testing identifier 4. Node path - Fallback, e.g., `html>body>div>ul>li:nth-child(2)` ### Using data-perfid For reliable performance tracking, add `data-perfid` attributes to elements you want to monitor: ```html