Skip to content

Commit 390fc90

Browse files
committed
[TwigComponent] Improve ComponentFactory performances
ComponentFactory Quick Optimization Minor change with.. mid impact (on large number of renders)
1 parent e514572 commit 390fc90

File tree

1 file changed

+27
-24
lines changed

1 file changed

+27
-24
lines changed

src/TwigComponent/src/ComponentFactory.php

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@
2525
*/
2626
final class ComponentFactory
2727
{
28+
private static $mountMethods = [];
29+
private static $preMountMethods = [];
30+
private static $postMountMethods = [];
31+
2832
/**
2933
* @param array<string, array> $config
3034
* @param array<class-string, string> $classMap
@@ -141,37 +145,39 @@ public function get(string $name): object
141145

142146
private function mount(object $component, array &$data): void
143147
{
144-
try {
145-
$method = (new \ReflectionClass($component))->getMethod('mount');
146-
} catch (\ReflectionException) {
147-
// no hydrate method
148-
return;
149-
}
150-
151148
if ($component instanceof AnonymousComponent) {
152149
$component->mount($data);
153150

154151
return;
155152
}
156153

157-
$parameters = [];
154+
if (!array_key_exists($component::class, self::$mountMethods)) {
155+
try {
156+
$mountMethod = self::$mountMethods[$component::class] = (new \ReflectionClass($component))->getMethod('mount');
157+
} catch (\ReflectionException) {
158+
self::$mountMethods[$component::class] = false;
159+
return;
160+
}
161+
}
158162

159-
foreach ($method->getParameters() as $refParameter) {
160-
$name = $refParameter->getName();
163+
if (false === $mountMethod ??= self::$mountMethods[$component::class]) {
164+
return;
165+
}
161166

162-
if (\array_key_exists($name, $data)) {
167+
$parameters = [];
168+
foreach ($mountMethod->getParameters() as $refParameter) {
169+
if (array_key_exists($name = $refParameter->getName(), $data)) {
163170
$parameters[] = $data[$name];
164-
165171
// remove the data element so it isn't used to set the property directly.
166172
unset($data[$name]);
167173
} elseif ($refParameter->isDefaultValueAvailable()) {
168174
$parameters[] = $refParameter->getDefaultValue();
169175
} else {
170-
throw new \LogicException(\sprintf('%s::mount() has a required $%s parameter. Make sure this is passed or make give a default value.', $component::class, $refParameter->getName()));
176+
throw new \LogicException(\sprintf('%s::mount() has a required $%s parameter. Make sure this is passed or make give a default value.', $component::class, $name));
171177
}
172178
}
173179

174-
$component->mount(...$parameters);
180+
$mountMethod->invoke($component, ...$parameters);
175181
}
176182

177183
private function preMount(object $component, array $data, ComponentMetadata $componentMetadata): array
@@ -180,10 +186,9 @@ private function preMount(object $component, array $data, ComponentMetadata $com
180186
$this->eventDispatcher->dispatch($event);
181187
$data = $event->getData();
182188

183-
foreach (AsTwigComponent::preMountMethods($component) as $method) {
184-
$newData = $component->{$method->name}($data);
185-
186-
if (null !== $newData) {
189+
$methods = self::$preMountMethods[$component::class] ??= AsTwigComponent::preMountMethods($component::class);
190+
foreach ($methods as $method) {
191+
if (null !== $newData = $method->invoke($component, $data)) {
187192
$data = $newData;
188193
}
189194
}
@@ -199,19 +204,17 @@ private function postMount(object $component, array $data, ComponentMetadata $co
199204
$event = new PostMountEvent($component, $data, $componentMetadata);
200205
$this->eventDispatcher->dispatch($event);
201206
$data = $event->getData();
202-
$extraMetadata = $event->getExtraMetadata();
203-
204-
foreach (AsTwigComponent::postMountMethods($component) as $method) {
205-
$newData = $component->{$method->name}($data);
206207

207-
if (null !== $newData) {
208+
$methods = self::$postMountMethods[$component::class] ??= AsTwigComponent::postMountMethods($component::class);
209+
foreach ($methods as $method) {
210+
if (null !== $newData = $method->invoke($component, $data)) {
208211
$data = $newData;
209212
}
210213
}
211214

212215
return [
213216
'data' => $data,
214-
'extraMetadata' => $extraMetadata,
217+
'extraMetadata' => $event->getExtraMetadata(),
215218
];
216219
}
217220

0 commit comments

Comments
 (0)