mirror of
https://github.com/filamentphp/filament.git
synced 2026-09-21 13:30:51 +08:00
Improve schema performance, especially in repeaters/builders (#18068)
* Cache default child schemas * safer * Return current component if the state path is the same * Add cachedComponentsByStatePath * Update HasComponents.php
This commit is contained in:
@@ -16,6 +16,11 @@ trait HasChildComponents
|
||||
*/
|
||||
protected array $childComponents = [];
|
||||
|
||||
/**
|
||||
* @var array<Schema> | null
|
||||
*/
|
||||
protected ?array $cachedDefaultChildSchemas = null;
|
||||
|
||||
/**
|
||||
* @param array<Component | Action | ActionGroup | string | Htmlable> | Closure $components
|
||||
*/
|
||||
@@ -67,8 +72,8 @@ trait HasChildComponents
|
||||
*/
|
||||
public function getChildSchema($key = null): ?Schema
|
||||
{
|
||||
if (filled($key) && array_key_exists($key, $containers = $this->getDefaultChildSchemas())) {
|
||||
return $containers[$key];
|
||||
if (filled($key) && array_key_exists($key, $this->cachedDefaultChildSchemas ??= $this->getDefaultChildSchemas())) {
|
||||
return $this->cachedDefaultChildSchemas[$key];
|
||||
}
|
||||
|
||||
$key ??= 'default';
|
||||
@@ -133,7 +138,7 @@ trait HasChildComponents
|
||||
}
|
||||
|
||||
return [
|
||||
...(array_key_exists('default', $this->childComponents) ? $this->getDefaultChildSchemas() : []),
|
||||
...(array_key_exists('default', $this->childComponents) ? ($this->cachedDefaultChildSchemas ??= $this->getDefaultChildSchemas()) : []),
|
||||
...array_reduce(
|
||||
array_keys($this->childComponents),
|
||||
function (array $carry, string $key): array {
|
||||
@@ -170,6 +175,11 @@ trait HasChildComponents
|
||||
return ['default' => $this->getChildSchema()];
|
||||
}
|
||||
|
||||
public function clearCachedDefaultChildSchemas(): void
|
||||
{
|
||||
$this->cachedDefaultChildSchemas = null;
|
||||
}
|
||||
|
||||
protected function cloneChildComponents(): static
|
||||
{
|
||||
foreach ($this->childComponents as $key => $childComponents) {
|
||||
|
||||
@@ -552,6 +552,11 @@ trait HasState
|
||||
|
||||
data_set($livewire, $this->getStatePath(), $this->evaluate($state));
|
||||
|
||||
// For components such as repeaters and builders, the default child schemas depend on the state of the component.
|
||||
// When loading state into these fields after the state is already present, the cached child schemas need to be
|
||||
// cleared so that they can be re-evaluated based on the new state. `rawState()` is called during this process.
|
||||
$this->clearCachedDefaultChildSchemas();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,12 +16,14 @@ class Get
|
||||
|
||||
$path = $this->component->resolveRelativeStatePath($path, $isAbsolute);
|
||||
|
||||
$component = $this->component->getRootContainer()->getComponentByStatePath(
|
||||
$path,
|
||||
withHidden: true,
|
||||
withAbsoluteStatePath: true,
|
||||
skipComponentChildContainersWhileSearching: $this->component,
|
||||
);
|
||||
$component = ($this->component->getStatePath() === $path)
|
||||
? $this->component
|
||||
: $this->component->getRootContainer()->getComponentByStatePath(
|
||||
$path,
|
||||
withHidden: true,
|
||||
withAbsoluteStatePath: true,
|
||||
skipComponentChildContainersWhileSearching: $this->component,
|
||||
);
|
||||
|
||||
if (! $component) {
|
||||
return data_get($livewire, $path);
|
||||
|
||||
@@ -16,12 +16,14 @@ class Set
|
||||
|
||||
$path = $this->component->resolveRelativeStatePath($path, $isAbsolute);
|
||||
|
||||
$component = $this->component->getRootContainer()->getComponentByStatePath(
|
||||
$path,
|
||||
withHidden: true,
|
||||
withAbsoluteStatePath: true,
|
||||
skipComponentChildContainersWhileSearching: $this->component,
|
||||
);
|
||||
$component = ($this->component->getStatePath() === $path)
|
||||
? $this->component
|
||||
: $this->component->getRootContainer()->getComponentByStatePath(
|
||||
$path,
|
||||
withHidden: true,
|
||||
withAbsoluteStatePath: true,
|
||||
skipComponentChildContainersWhileSearching: $this->component,
|
||||
);
|
||||
|
||||
$state = $this->component->evaluate($state);
|
||||
|
||||
|
||||
@@ -29,6 +29,11 @@ trait HasComponents
|
||||
*/
|
||||
protected ?array $cachedComponents = null;
|
||||
|
||||
/**
|
||||
* @var array<array<array<string, Component>>>
|
||||
*/
|
||||
protected array $cachedComponentsByStatePath = [];
|
||||
|
||||
/**
|
||||
* @param array<Component | Action | ActionGroup | string | Htmlable> | Component | Action | ActionGroup | string | Htmlable | Closure $components
|
||||
*/
|
||||
@@ -37,6 +42,7 @@ trait HasComponents
|
||||
$this->components = $components;
|
||||
$this->cachedComponents = null;
|
||||
$this->cachedFlatComponents = [];
|
||||
$this->cachedComponentsByStatePath = [];
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -226,7 +232,7 @@ trait HasComponents
|
||||
return null;
|
||||
};
|
||||
|
||||
return $search($this);
|
||||
return $this->cachedComponentsByStatePath[$withHidden][$skipComponentChildContainersWhileSearching ? spl_object_id($skipComponentChildContainersWhileSearching) : null][$statePath] ??= $search($this);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -352,6 +358,7 @@ trait HasComponents
|
||||
|
||||
$this->cachedComponents = null;
|
||||
$this->cachedFlatComponents = [];
|
||||
$this->cachedComponentsByStatePath = [];
|
||||
}
|
||||
|
||||
return $this;
|
||||
|
||||
Reference in New Issue
Block a user