Skip to content

Commit 19b09c4

Browse files
committed
[TwigComponent] Simplify the ComponentLoggerListener
* Clean unused code * Reduce memory usage * Optimize class/templates lookup
1 parent 45c0ffe commit 19b09c4

File tree

5 files changed

+29
-77
lines changed

5 files changed

+29
-77
lines changed

composer.json

-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040
"symfony/framework-bundle": "^5.4|^6.0|^7.0",
4141
"symfony/phpunit-bridge": "^6.0|^7.0",
4242
"symfony/stimulus-bundle": "^2.9.1",
43-
"symfony/stopwatch": "^5.4|^6.0|^7.0",
4443
"symfony/twig-bundle": "^5.4|^6.0|^7.0",
4544
"symfony/webpack-encore-bundle": "^1.15"
4645
},

config/debug.php

-3
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,6 @@
2121
$container->services()
2222

2323
->set('ux.twig_component.component_logger_listener', TwigComponentLoggerListener::class)
24-
->args([
25-
service('debug.stopwatch')->ignoreOnInvalid(),
26-
])
2724
->tag('kernel.event_subscriber')
2825

2926
->set('ux.twig_component.data_collector', TwigComponentDataCollector::class)

src/DataCollector/TwigComponentDataCollector.php

+9-4
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,10 @@
2525

2626
/**
2727
* @author Simon André <[email protected]>
28+
*
29+
* @internal
2830
*/
29-
class TwigComponentDataCollector extends AbstractDataCollector implements LateDataCollectorInterface
31+
final class TwigComponentDataCollector extends AbstractDataCollector implements LateDataCollectorInterface
3032
{
3133
private bool $hasStub;
3234

@@ -99,6 +101,9 @@ private function collectDataFromLogger(): void
99101
$renders = [];
100102
$ongoingRenders = [];
101103

104+
$classStubs = [];
105+
$templatePaths = [];
106+
102107
foreach ($this->logger->getEvents() as [$event, $profile]) {
103108
if ($event instanceof PreRenderEvent) {
104109
$mountedComponent = $event->getMountedComponent();
@@ -110,9 +115,9 @@ private function collectDataFromLogger(): void
110115
$components[$componentName] ??= [
111116
'name' => $componentName,
112117
'class' => $componentClass,
113-
'class_stub' => $this->hasStub ? new ClassStub($componentClass) : $componentClass,
114-
'template' => $metadata->getTemplate(),
115-
'template_path' => $this->resolveTemplatePath($metadata->getTemplate()), // defer ? lazy ?
118+
'class_stub' => $classStubs[$componentClass] ??= ($this->hasStub ? new ClassStub($componentClass) : $componentClass),
119+
'template' => $template = $metadata->getTemplate(),
120+
'template_path' => $templatePaths[$template] ??= $this->resolveTemplatePath($template),
116121
'render_count' => 0,
117122
'render_time' => 0,
118123
];

src/EventListener/TwigComponentLoggerListener.php

+14-49
Original file line numberDiff line numberDiff line change
@@ -12,90 +12,55 @@
1212
namespace Symfony\UX\TwigComponent\EventListener;
1313

1414
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
15-
use Symfony\Component\Stopwatch\Stopwatch;
1615
use Symfony\Contracts\Service\ResetInterface;
17-
use Symfony\UX\TwigComponent\Event\PostMountEvent;
1816
use Symfony\UX\TwigComponent\Event\PostRenderEvent;
19-
use Symfony\UX\TwigComponent\Event\PreCreateForRenderEvent;
20-
use Symfony\UX\TwigComponent\Event\PreMountEvent;
2117
use Symfony\UX\TwigComponent\Event\PreRenderEvent;
2218

2319
/**
2420
* @author Simon André <[email protected]>
21+
*
22+
* @internal
2523
*/
26-
class TwigComponentLoggerListener implements EventSubscriberInterface, ResetInterface
24+
final class TwigComponentLoggerListener implements EventSubscriberInterface, ResetInterface
2725
{
2826
private array $events = [];
2927

30-
public function __construct(private ?Stopwatch $stopwatch = null)
31-
{
32-
}
33-
3428
public static function getSubscribedEvents(): array
3529
{
3630
return [
37-
PreCreateForRenderEvent::class => [
38-
// High priority: start the stopwatch as soon as possible
39-
['onPreCreateForRender', 255],
40-
// Low priority: check `event::getRenderedString()` as late as possible
41-
['onPostCreateForRender', -255],
42-
],
43-
PreMountEvent::class => ['onPreMount', 255],
44-
PostMountEvent::class => ['onPostMount', -255],
4531
PreRenderEvent::class => ['onPreRender', 255],
4632
PostRenderEvent::class => ['onPostRender', -255],
4733
];
4834
}
4935

36+
/**
37+
* @return list<array{
38+
* PreRenderEvent|PostRenderEvent,
39+
* array{float, int},
40+
* }>
41+
*/
5042
public function getEvents(): array
5143
{
5244
return $this->events;
5345
}
5446

55-
public function onPreCreateForRender(PreCreateForRenderEvent $event): void
56-
{
57-
$this->stopwatch?->start($event->getName(), 'twig_component');
58-
$this->logEvent($event);
59-
}
60-
61-
private function logEvent(object $event): void
62-
{
63-
$this->events[] = [$event, [microtime(true), memory_get_usage(true)]];
64-
}
65-
66-
public function onPostCreateForRender(PreCreateForRenderEvent $event): void
67-
{
68-
if (\is_string($event->getRenderedString())) {
69-
$this->stopwatch?->stop($event->getName());
70-
$this->logEvent($event);
71-
}
72-
}
73-
74-
public function onPreMount(PreMountEvent $event): void
75-
{
76-
$this->logEvent($event);
77-
}
78-
79-
public function onPostMount(PostMountEvent $event): void
80-
{
81-
$this->logEvent($event);
82-
}
83-
8447
public function onPreRender(PreRenderEvent $event): void
8548
{
8649
$this->logEvent($event);
8750
}
8851

8952
public function onPostRender(PostRenderEvent $event): void
9053
{
91-
if ($this->stopwatch?->isStarted($name = $event->getMountedComponent()->getName())) {
92-
$this->stopwatch->stop($name);
93-
}
9454
$this->logEvent($event);
9555
}
9656

9757
public function reset(): void
9858
{
9959
$this->events = [];
10060
}
61+
62+
private function logEvent(object $event): void
63+
{
64+
$this->events[] = [$event, [microtime(true), memory_get_usage(true)]];
65+
}
10166
}

tests/Unit/EventListener/TwigComponentLoggerListenerTest.php

+6-20
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,7 @@
1414
use PHPUnit\Framework\TestCase;
1515
use Symfony\UX\TwigComponent\ComponentAttributes;
1616
use Symfony\UX\TwigComponent\ComponentMetadata;
17-
use Symfony\UX\TwigComponent\Event\PostMountEvent;
1817
use Symfony\UX\TwigComponent\Event\PostRenderEvent;
19-
use Symfony\UX\TwigComponent\Event\PreCreateForRenderEvent;
20-
use Symfony\UX\TwigComponent\Event\PreMountEvent;
2118
use Symfony\UX\TwigComponent\Event\PreRenderEvent;
2219
use Symfony\UX\TwigComponent\EventListener\TwigComponentLoggerListener;
2320
use Symfony\UX\TwigComponent\MountedComponent;
@@ -32,31 +29,20 @@ public function testLoggerStoreEvents(): void
3229
$logger = new TwigComponentLoggerListener();
3330
$this->assertSame([], $logger->getEvents());
3431

35-
$eventA = new PreCreateForRenderEvent('a');
36-
$logger->onPreCreateForRender($eventA);
37-
38-
$eventB = new PreCreateForRenderEvent('b');
39-
$logger->onPreCreateForRender($eventB);
40-
41-
$eventC = new PreMountEvent(new \stdClass(), [], new ComponentMetadata([]));
42-
$logger->onPreMount($eventC);
43-
$eventD = new PostMountEvent(new \stdClass(), [], new ComponentMetadata([]));
44-
$logger->onPostMount($eventD);
45-
4632
$mounted = new MountedComponent('foo', new \stdClass(), new ComponentAttributes([]));
47-
$eventE = new PreRenderEvent($mounted, new ComponentMetadata(['template' => 'bar']), []);
48-
$logger->onPreRender($eventE);
49-
$eventF = new PostRenderEvent($mounted);
50-
$logger->onPostRender($eventF);
33+
$eventA = new PreRenderEvent($mounted, new ComponentMetadata(['template' => 'bar']), []);
34+
$logger->onPreRender($eventA);
35+
$eventB = new PostRenderEvent($mounted);
36+
$logger->onPostRender($eventB);
5137

52-
$this->assertSame([$eventA, $eventB, $eventC, $eventD, $eventE, $eventF], array_column($logger->getEvents(), 0));
38+
$this->assertSame([$eventA, $eventB], array_column($logger->getEvents(), 0));
5339
}
5440

5541
public function testLoggerReset(): void
5642
{
5743
$logger = new TwigComponentLoggerListener();
5844

59-
$logger->onPreCreateForRender(new PreCreateForRenderEvent('foo'));
45+
$logger->onPreRender(new PreRenderEvent(new MountedComponent('foo', new \stdClass(), new ComponentAttributes([])), new ComponentMetadata(['template' => 'bar']), []));
6046
$this->assertNotSame([], $logger->getEvents());
6147

6248
$logger->reset();

0 commit comments

Comments
 (0)