measure( 'livecomponent.counter.increment', PerformanceCategory::CUSTOM, function () use ($tracker) { // 1. Schema Derive/Cache $tracker->measure( 'livecomponent.schema.derive', PerformanceCategory::CACHE, function () { usleep(500); // 0.5ms - Schema aus Cache }, ['component' => 'counter'] ); // 2. Action Execute $tracker->measure( 'livecomponent.action.execute', PerformanceCategory::CUSTOM, function () { usleep(2000); // 2ms - Business Logic }, ['action' => 'increment', 'component' => 'counter'] ); // 3. State Validate $tracker->measure( 'livecomponent.state.validate', PerformanceCategory::CUSTOM, function () { usleep(300); // 0.3ms - Validation }, ['component' => 'counter'] ); // 4. Lifecycle Hook onUpdate $tracker->measure( 'livecomponent.lifecycle.onUpdate', PerformanceCategory::CUSTOM, function () { usleep(100); // 0.1ms - Hook }, ['component' => 'counter'] ); }, ['component' => 'counter', 'action' => 'increment'] ); // Timeline ausgeben echo "\nComponent Action Timeline:\n"; $timeline = $tracker->generateTimeline(); foreach ($timeline as $event) { $indent = str_repeat(' ', $event['depth']); echo sprintf( " %s[%s] %s (%.2fms)\n", $indent, $event['category'], $event['name'], $event['duration_ms'] ); } echo "\n" . str_repeat('=', 50) . "\n\n"; // Example 2: Component Render Profiling echo "Example 2: Component Render Profiling\n"; echo str_repeat('-', 50) . "\n"; $tracker->reset(); // Simuliere Component Render mit Cache $tracker->measure( 'livecomponent.render.user-card', PerformanceCategory::VIEW, function () use ($tracker) { // 1. Cache Get (Hit) $tracker->measure( 'livecomponent.cache.get', PerformanceCategory::CACHE, function () { usleep(300); // 0.3ms - Cache Hit return ['html' => '
cached
', 'needs_refresh' => false]; }, ['component' => 'user-card'] ); }, ['component' => 'user-card'] ); // Simuliere Component Render ohne Cache $tracker->measure( 'livecomponent.render.product-list', PerformanceCategory::VIEW, function () use ($tracker) { // 1. Cache Get (Miss) $tracker->measure( 'livecomponent.cache.get', PerformanceCategory::CACHE, function () { usleep(200); // 0.2ms - Cache Miss return ['html' => null, 'needs_refresh' => false]; }, ['component' => 'product-list'] ); // 2. Get Render Data $tracker->measure( 'livecomponent.getRenderData', PerformanceCategory::CUSTOM, function () { usleep(1000); // 1ms - Data preparation }, ['component' => 'product-list'] ); // 3. Template Render $tracker->measure( 'livecomponent.template.render', PerformanceCategory::TEMPLATE, function () use ($tracker) { usleep(5000); // 5ms - Template rendering // Nested: Template processors $tracker->measure( 'template.processor.placeholder', PerformanceCategory::TEMPLATE, function () { usleep(1000); // 1ms } ); $tracker->measure( 'template.processor.component', PerformanceCategory::TEMPLATE, function () { usleep(2000); // 2ms } ); }, ['component' => 'product-list', 'template' => 'components/product-list.view.php'] ); // 4. Cache Set $tracker->measure( 'livecomponent.cache.set', PerformanceCategory::CACHE, function () { usleep(400); // 0.4ms - Cache storage }, ['component' => 'product-list'] ); }, ['component' => 'product-list'] ); echo "\nComponent Render Timeline:\n"; $timeline = $tracker->generateTimeline(); foreach ($timeline as $event) { $indent = str_repeat(' ', $event['depth']); $contextInfo = !empty($event['context']['template']) ? " ({$event['context']['template']})" : ''; echo sprintf( " %s[%s] %s%s (%.2fms self, %.2fms total)\n", $indent, $event['category'], $event['name'], $contextInfo, $event['self_time_ms'], $event['duration_ms'] ); } echo "\n" . str_repeat('=', 50) . "\n\n"; // Example 3: Multiple Component Actions (Flamegraph) echo "Example 3: Multiple Component Actions (Flamegraph)\n"; echo str_repeat('-', 50) . "\n"; $tracker->reset(); // Simuliere mehrere Component Actions for ($i = 0; $i < 3; $i++) { $tracker->measure( 'livecomponent.search.updateQuery', PerformanceCategory::CUSTOM, function () use ($tracker) { $tracker->measure( 'livecomponent.action.execute', PerformanceCategory::CUSTOM, function () { usleep(3000); // 3ms } ); $tracker->measure( 'livecomponent.state.validate', PerformanceCategory::CUSTOM, function () { usleep(500); // 0.5ms } ); }, ['component' => 'search', 'action' => 'updateQuery'] ); } echo "\nFlamegraph Data (aggregated):\n"; $flamegraph = $tracker->generateFlamegraph(); foreach ($flamegraph as $entry) { echo sprintf( " %s → %.1f samples\n", $entry['stack_trace'], $entry['samples'] ); } echo "\n" . str_repeat('=', 50) . "\n\n"; // Example 4: Performance Budget Validation for LiveComponents echo "Example 4: Performance Budget Validation\n"; echo str_repeat('-', 50) . "\n"; $budgets = [ 'livecomponent.action.execute' => 5, // max 5ms for actions 'livecomponent.template.render' => 10, // max 10ms for templates 'livecomponent.cache.get' => 1, // max 1ms for cache 'livecomponent.render' => 20, // max 20ms total render ]; $violations = []; foreach ($timeline as $event) { foreach ($budgets as $operation => $budget) { if (str_contains($event['name'], $operation)) { if ($event['duration_ms'] > $budget) { $violations[] = [ 'operation' => $event['name'], 'component' => $event['context']['component'] ?? 'unknown', 'duration' => $event['duration_ms'], 'budget' => $budget, 'exceeded_by' => $event['duration_ms'] - $budget, 'percentage' => (($event['duration_ms'] - $budget) / $budget) * 100 ]; } } } } if (!empty($violations)) { echo "\n⚠️ Performance Budget Violations:\n"; foreach ($violations as $violation) { echo sprintf( " • [%s] %s: %.2fms (budget: %.2fms, exceeded by %.2fms / %.1f%%)\n", $violation['component'], $violation['operation'], $violation['duration'], $violation['budget'], $violation['exceeded_by'], $violation['percentage'] ); } } else { echo "\n✅ All LiveComponent operations within performance budget!\n"; } echo "\n" . str_repeat('=', 50) . "\n\n"; // Example 5: Export für Chrome DevTools echo "Example 5: Chrome DevTools Export\n"; echo str_repeat('-', 50) . "\n"; // Generate full timeline with all examples $fullTimeline = $tracker->generateTimeline(); // Convert to Chrome Trace Event Format $traceEvents = []; foreach ($fullTimeline as $event) { // Begin Event $traceEvents[] = [ 'name' => $event['name'], 'cat' => $event['category'], 'ph' => 'B', 'ts' => (int)($event['start_time'] * 1_000_000), 'pid' => 1, 'tid' => 1, 'args' => $event['context'] ]; // End Event $traceEvents[] = [ 'name' => $event['name'], 'cat' => $event['category'], 'ph' => 'E', 'ts' => (int)($event['end_time'] * 1_000_000), 'pid' => 1, 'tid' => 1 ]; } $chromeTrace = [ 'traceEvents' => $traceEvents, 'displayTimeUnit' => 'ms', 'otherData' => [ 'version' => '1.0', 'framework' => 'Custom PHP Framework - LiveComponents', 'profiler' => 'NestedPerformanceTracker' ] ]; $chromeTraceFile = __DIR__ . '/../tests/tmp/livecomponent-trace.json'; @mkdir(dirname($chromeTraceFile), 0755, true); file_put_contents($chromeTraceFile, json_encode($chromeTrace, JSON_PRETTY_PRINT)); echo "\nChrome Trace saved to: {$chromeTraceFile}\n"; echo "View in Chrome DevTools:\n"; echo " 1. Open Chrome and navigate to: chrome://tracing\n"; echo " 2. Click 'Load' and select: {$chromeTraceFile}\n"; echo " 3. Explore the LiveComponent lifecycle timeline\n"; echo "\n" . str_repeat('=', 50) . "\n\n"; // Summary echo "✅ LiveComponent Performance Profiling Examples completed!\n\n"; echo "Generated Files:\n"; echo " • {$chromeTraceFile}\n\n"; echo "Key Insights:\n"; echo " • LiveComponent actions are fully traced with nested operations\n"; echo " • Component render pipeline is profiled (cache → render → template)\n"; echo " • Lifecycle hooks (onMount, onUpdate) are measured\n"; echo " • Performance budgets can be validated per component\n"; echo " • Chrome DevTools integration for visual analysis\n\n"; echo "Next Steps:\n"; echo " 1. Load trace in Chrome DevTools for visual timeline\n"; echo " 2. Identify slow component actions and rendering\n"; echo " 3. Set performance budgets for production monitoring\n"; echo " 4. Integrate with logging for continuous profiling\n\n";