Hi,
we’re currently facing performance issues in the Panel, with a total loading time of around 2000 ms. We have about 100 regular (physical) content pages, which are not a problem.
The bottleneck seems to be the creation of virtual pages. We fetch data from an API and store the raw data in a cache. On the parent page, we override the children() method to return a new Pages object:
public function children(): Pages
{
if ($this->children instanceof Pages) {
return $this->children;
}
return $this->children = $this->resource->toPages(parent: $this);
}
This generates roughly 3,000 virtual pages. The toPages() method uses Page::factory() to create new Page objects from the cached data, then returns a mapped array of these pages:
public function toPages(Page $parent): Pages
{
$data = $this->data();
$pagesData = array_map(
function ($item) use ($parent) {
$fields = $this->mapFieldsFromData($this->config->map(), $item);
$page = [
...$fields,
'template' => $this->config['template'],
'model' => $this->config['model'],
'parent' => $parent,
];
return $page;
},
$data,
);
$pages = array_map(
function ($item) {
// APIRecord extends Page class
return APIRecord::factory($item);
}, $pagesData
);
return new Pages($pages, $parent);
}
When we skip the factory calls, loading time drops to about 450 ms, but as far as I know, creating a Pages object requires an array of Page objects, which we can only get by actually creating them for each virtual page — is that correct? We already tried replacing the $fields variable with only the slug and title which only saves around 100ms.
We recently updated to Kirby 5.1 and started using Kirby Turbo, hoping for performance improvements. However, it seems that virtual pages are not cached and therefore don’t benefit from Turbo’s optimizations.
Any tips or insights on improving performance in this scenario would be greatly appreciated.
Thanks in advance!