Skip to content

refactor(view): use PHP's includes#1980

Draft
brendt wants to merge 20 commits into3.xfrom
view-includes
Draft

refactor(view): use PHP's includes#1980
brendt wants to merge 20 commits into3.xfrom
view-includes

Conversation

@brendt
Copy link
Member

@brendt brendt commented Feb 17, 2026

The idea of this PR is that we use PHP's include for view components instead of parsing everything in one file. This solves issues like colliding imports across view components.

The problem however is the performance hit: the test I added yields 0.0068130493164062 with our current approach, 0.10852599143982 with the include approach. On top of that, with include we move the performance hit to the render phase (which can't be cached).

Maybe there's room for optimizations, but preliminary results aren't good.

@brendt brendt marked this pull request as draft February 17, 2026 08:06
@innocenzi innocenzi changed the title feat(view): use PHP's includes refactor(view): use PHP's includes Feb 17, 2026
}

private function makeElement(Token $token, ?Element $parent): ?Element
public function make(Token $token, Element $parent): ?Element
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ElementFactory now always requires a parent/root element

}

$children = [];
$element->setParent($parent);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refactored parent/child setting because not all elements have children, but all have a parent.

{
$this->parent = $parent;

$this->parent->setChildren([...$this->parent->getChildren(), $this]);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See before: not all elements have children but all have a parent

use Tempest\View\Parser\Token;
use Tempest\View\WithToken;

final class PhpElement implements Element, WithToken, HasImports
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Represents a block of PHP code, currently only used to extract imports


public function getImports(): array
{
preg_match_all('/^\s*use .*;/m', $this->content, $matches);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently we're still using a regex, we could improve if needed once this refactor works

use Tempest\View\Element;
use Tempest\View\HasImports;

final class RootElement implements Element, HasImports
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This new RootElement is used as… the root.

It ensures a ViewComponentElement has a parent where it can gather imports from

{
$imports = [];

foreach ($this->children as $child) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We only want to resolve imports from PhpElements, not from sibling ViewComponent elements. That's why we check instanceof PhpElement here

return sprintf('new \%s([%s])', ImmutableArray::class, implode(', ', $entries));
}

public function getImports(): array
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

View components can be nested, and we need to recursively resolve all imports.

Writing this reminds me: we also need to check for sibling PhpElements in the same file still. That's still TODO


// 4. Map to elements
$elements = $this->mapToElements($ast);
$rootElement = $this->mapToElements($ast);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refactoring to accomodate the new RootElement

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants