Skip to content

Commit 02d3274

Browse files
committed
feature #3077 [LiveComponent] Improve performance for LiveUrlSubscriber (Danny van Wijk)
This PR was merged into the 2.x branch. Discussion ---------- [LiveComponent] Improve performance for LiveUrlSubscriber | Q | A | ------------- | --- | Bug fix? |no | New feature? | no <!-- please update src/**/CHANGELOG.md files --> | Docs? | no <!-- required for new features --> | Issues | Fix #... <!-- prefix each issue number with "Fix #", no need to create an issue if none exist, explain below instead --> | License | MIT <!-- Replace this notice by a description of your feature/bugfix. This will help reviewers and should be a good start for the documentation. Additionally (see https://symfony.com/releases): - Always add tests and ensure they pass. - For new features, provide some code snippets to help understand usage. - Features and deprecations must be submitted against branch main. - Update/add documentation as required (we can help!) - Changelog entry should follow https://symfony.com/doc/current/contributing/code/conventions.html#writing-a-changelog-entry - Never break backward compatibility (see https://symfony.com/bc). --> Improve performance by removing heavy services if not needed. Commits ------- d78b50b Improve performance for LiveUrlSubscriber
2 parents 6e14d4a + d78b50b commit 02d3274

File tree

2 files changed

+40
-16
lines changed

2 files changed

+40
-16
lines changed

src/LiveComponent/src/DependencyInjection/LiveComponentExtension.php

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
2525
use Symfony\Component\DependencyInjection\Parameter;
2626
use Symfony\Component\DependencyInjection\Reference;
27+
use Symfony\Component\Routing\RouterInterface;
2728
use Symfony\UX\LiveComponent\Attribute\AsLiveComponent;
2829
use Symfony\UX\LiveComponent\ComponentValidator;
2930
use Symfony\UX\LiveComponent\ComponentValidatorInterface;
@@ -138,12 +139,10 @@ function (ChildDefinition $definition, AsLiveComponent $attribute) {
138139
;
139140

140141
$container->register('ux.live_component.live_url_subscriber', LiveUrlSubscriber::class)
141-
->setArguments([
142-
new Reference('ux.live_component.metadata_factory'),
143-
new Reference('ux.live_component.component_hydrator'),
144-
new Reference('router'),
145-
])
146142
->addTag('kernel.event_subscriber')
143+
->addTag('container.service_subscriber', ['key' => LiveComponentHydrator::class, 'id' => 'ux.live_component.component_hydrator'])
144+
->addTag('container.service_subscriber', ['key' => LiveComponentMetadataFactory::class, 'id' => 'ux.live_component.metadata_factory'])
145+
->addTag('container.service_subscriber', ['key' => RouterInterface::class, 'id' => 'router'])
147146
;
148147

149148
$container->register('ux.live_component.live_responder', LiveResponder::class);

src/LiveComponent/src/EventListener/LiveUrlSubscriber.php

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,29 +11,38 @@
1111

1212
namespace Symfony\UX\LiveComponent\EventListener;
1313

14+
use Psr\Container\ContainerInterface;
1415
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
1516
use Symfony\Component\HttpKernel\Event\ResponseEvent;
1617
use Symfony\Component\HttpKernel\KernelEvents;
1718
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
1819
use Symfony\Component\Routing\RouterInterface;
20+
use Symfony\Contracts\Service\ServiceSubscriberInterface;
1921
use Symfony\UX\LiveComponent\LiveComponentHydrator;
2022
use Symfony\UX\LiveComponent\Metadata\LiveComponentMetadataFactory;
2123
use Symfony\UX\TwigComponent\MountedComponent;
2224

2325
/**
2426
* @internal
2527
*/
26-
class LiveUrlSubscriber implements EventSubscriberInterface
28+
class LiveUrlSubscriber implements EventSubscriberInterface, ServiceSubscriberInterface
2729
{
2830
private const URL_HEADER = 'X-Live-Url';
2931

3032
public function __construct(
31-
private LiveComponentMetadataFactory $metadataFactory,
32-
private LiveComponentHydrator $liveComponentHydrator,
33-
private RouterInterface $router,
33+
private ContainerInterface $container,
3434
) {
3535
}
3636

37+
public static function getSubscribedServices(): array
38+
{
39+
return [
40+
LiveComponentMetadataFactory::class,
41+
LiveComponentHydrator::class,
42+
RouterInterface::class,
43+
];
44+
}
45+
3746
public function onKernelResponse(ResponseEvent $event): void
3847
{
3948
$request = $event->getRequest();
@@ -68,10 +77,10 @@ private function extractUrlLiveProps(MountedComponent $mounted): array
6877
{
6978
$pathProps = $queryProps = [];
7079

71-
$mountedMetadata = $this->metadataFactory->getMetadata($mounted->getName());
80+
$mountedMetadata = $this->getMetadataFactory()->getMetadata($mounted->getName());
7281

7382
if ([] !== $urlMappings = $mountedMetadata->getAllUrlMappings($mounted->getComponent())) {
74-
$dehydratedProps = $this->liveComponentHydrator->dehydrate($mounted->getComponent(), $mounted->getAttributes(), $mountedMetadata);
83+
$dehydratedProps = $this->getLiveComponentHydrator()->dehydrate($mounted->getComponent(), $mounted->getAttributes(), $mountedMetadata);
7584
$props = $dehydratedProps->getProps();
7685

7786
foreach ($urlMappings as $name => $urlMapping) {
@@ -95,14 +104,15 @@ private function generateNewLiveUrl(string $previousUrl, array $pathProps, array
95104
$newQueryString = $previousUrlParsed['query'] ?? '';
96105

97106
if ([] !== $pathProps) {
98-
$context = $this->router->getContext();
107+
$router = $this->getRouter();
108+
$context = $router->getContext();
99109
try {
100110
// Re-create a context for the URL rendering the current LiveComponent
101111
$tmpContext = clone $context;
102112
$tmpContext->setMethod('GET');
103-
$this->router->setContext($tmpContext);
113+
$router->setContext($tmpContext);
104114

105-
$routeMatched = $this->router->match($previousUrlParsed['path']);
115+
$routeMatched = $router->match($previousUrlParsed['path']);
106116
$routeParams = [];
107117
foreach ($routeMatched as $k => $v) {
108118
if ('_route' === $k || '_controller' === $k) {
@@ -111,11 +121,11 @@ private function generateNewLiveUrl(string $previousUrl, array $pathProps, array
111121
$routeParams[$k] = \array_key_exists($k, $pathProps) ? $pathProps[$k] : $v;
112122
}
113123

114-
$newUrl = $this->router->generate($routeMatched['_route'], $routeParams);
124+
$newUrl = $router->generate($routeMatched['_route'], $routeParams);
115125
} catch (ResourceNotFoundException) {
116126
// reuse the previous URL path
117127
} finally {
118-
$this->router->setContext($context);
128+
$router->setContext($context);
119129
}
120130
}
121131

@@ -131,4 +141,19 @@ private function generateNewLiveUrl(string $previousUrl, array $pathProps, array
131141

132142
return $newUrl.($newQueryString ? '?'.$newQueryString : '');
133143
}
144+
145+
private function getMetadataFactory(): LiveComponentMetadataFactory
146+
{
147+
return $this->container->get(LiveComponentMetadataFactory::class);
148+
}
149+
150+
private function getLiveComponentHydrator(): LiveComponentHydrator
151+
{
152+
return $this->container->get(LiveComponentHydrator::class);
153+
}
154+
155+
private function getRouter(): RouterInterface
156+
{
157+
return $this->container->get(RouterInterface::class);
158+
}
134159
}

0 commit comments

Comments
 (0)