Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TwigComponent] Improve BlockStack performances #2343

Merged
merged 1 commit into from
Nov 7, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 12 additions & 8 deletions src/TwigComponent/src/BlockStack.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,15 @@ final class BlockStack
*/
private array $stack;

/**
* @var array<class-string, int>
*/
private static array $templateIndexStack = [];

public function convert(array $blocks, int $targetEmbeddedTemplateIndex): array
{
$newBlocks = [];
$hostEmbeddedTemplateIndex = null;
foreach ($blocks as $blockName => $block) {
// Keep already converted outer blocks untouched
if (str_starts_with($blockName, self::OUTER_BLOCK_PREFIX)) {
Expand All @@ -41,7 +47,7 @@ public function convert(array $blocks, int $targetEmbeddedTemplateIndex): array
// Determine the location of the block where it is defined in the host Template.
// Each component has its own embedded template. That template's index uniquely
// identifies the block definition.
$hostEmbeddedTemplateIndex = $this->findHostEmbeddedTemplateIndex();
$hostEmbeddedTemplateIndex ??= $this->findHostEmbeddedTemplateIndex();

// Change the name of outer blocks to something unique so blocks of nested components aren't overridden,
// which otherwise might cause a recursion loop when nesting components.
Expand Down Expand Up @@ -69,12 +75,10 @@ private function findHostEmbeddedTemplateIndex(): int
{
$backtrace = debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS | \DEBUG_BACKTRACE_PROVIDE_OBJECT);

$componentTemplateClassName = null;

foreach ($backtrace as $trace) {
if (isset($trace['object']) && $trace['object'] instanceof Template) {
$classname = $trace['object']::class;
$templateIndex = $this->getTemplateIndexFromTemplateClassname($classname);
$templateIndex = self::getTemplateIndexFromTemplateClassname($classname);
if ($templateIndex) {
// If there's no template index, then we're in a component template
// and we need to go up until we find the embedded template
Expand All @@ -93,7 +97,7 @@ private function findCallingEmbeddedTemplateIndex(): int

foreach ($backtrace as $trace) {
if (isset($trace['object']) && $trace['object'] instanceof Template) {
return $this->getTemplateIndexFromTemplateClassname($trace['object']::class);
return self::getTemplateIndexFromTemplateClassname($trace['object']::class);
}
}
}
Expand All @@ -108,7 +112,7 @@ private function findHostEmbeddedTemplateIndexFromCaller(): int
foreach ($backtrace as $trace) {
if (isset($trace['object']) && $trace['object'] instanceof Template) {
$classname = $trace['object']::class;
$templateIndex = $this->getTemplateIndexFromTemplateClassname($classname);
$templateIndex = self::getTemplateIndexFromTemplateClassname($classname);
if (null === $renderer) {
if ($templateIndex) {
// This class is an embedded template.
Expand Down Expand Up @@ -139,8 +143,8 @@ private function findHostEmbeddedTemplateIndexFromCaller(): int
return 0;
}

private function getTemplateIndexFromTemplateClassname(string $classname): int
private static function getTemplateIndexFromTemplateClassname(string $classname): int
{
return (int) substr($classname, strrpos($classname, '___') + 3);
return self::$templateIndexStack[$classname] ??= (int) substr($classname, strrpos($classname, '___') + 3);
}
}