Hello!
I’m having performance issues with one of my Kirby websites.
For this project, my goal was to fetch project-related events via an API and combine them with content from Kirby CMS, such as images and additional event information.
So basically I built myself a custom page model plugin that uses Merging content sources | Kirby CMS as a basis for a content merge.
# more code
public function children(): Pages
{
if ($this->isUnlisted()) {
// unlisted = archived projects, ignore those
return Pages::factory([], $this);
}
if ($this->children instanceof Pages) {
return $this->children;
}
$pages = new Pages();
$arrangementId = $this->arrangementId()->value();
$results = site()->getProjectAllArrangementEvents()[$arrangementId] ?? [];
$parameters = array_column(
site()->getProjectAllOptions(),
'value'
);
if ($results) {
foreach ($results as $event) {
// only fetch events that are public!
if (
!is_array($event) ||
($event['public_status'] ?? null) != 1 ||
empty($event['event_id'])
) {
continue;
}
// Get the page on disk, if it exists
$slug = Str::slug(
$this->arrangementId() . '_' . $event['event_id']
);
$page = $this->subpages()->find($slug);
$content = [];
foreach ($parameters as $parameter) {
if (isset($event[$parameter])) {
// Prefix Project fields to avoid conflicts with Kirby fields
$content['project_' . $parameter] = $event[$parameter];
}
}
// Custom Kirby fields
$content['kirby_more_event_info'] =
$this->kirbySubtitle()->value() ?: '';
$content['kirby_additional_info'] =
$this->kirbyAdditionalInfo()->value() ?: '';
// ... more fields ...
$virtualPage = Page::factory([
'slug' => $slug,
'template' => 'calendar_event_project',
'model' => 'calendar_event_project',
'parent' => $this,
]);
try {
$virtualPage->changeStorage(MixedStorage::class);
$virtualContent = $content;
$virtualContent['uuid'] =
$page?->uuid()->toString() ?? Uuid::generate();
$virtualContent['kirby_panel_url'] =
$virtualPage->panel()->url();
$languageCode =
kirby()->language()?->code() ?? 'default';
$virtualPage->storage()->writeVirtual(
versionId: VersionId::latest(),
language: Language::ensure($languageCode),
data: $virtualContent
);
$pages->add($virtualPage);
} catch (Exception $e) {
error_log(
'Failed to create virtual page for event ' .
$event['event_id'] . ': ' .
$e->getMessage()
);
}
}
}
return $this->children = $pages;
}
Info:
in getProjectAllArrangementEvents() I cache the response which improved the performance a lot. But the php processing is still intense ![]()
My content structure looks like this:
01_project
|_event_01
|_event_02
|_event_03
...
|_event_99_or_more
When I first built this, the number of pages using this page model was much smaller. By now, there are roughly 100 times as many pages, and I’ve noticed that the website has become significantly slower as a result.
so my question is:
Does anyone have a hint on how to make this faster … or what would be a way to prevent this kind of performance lag when working with a large number of virtual pages?
Or, if you have an idea for a better approach than using virtual pages in this case, I’d be very interested to hear it ![]()
Thanks a lot!