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

[Craft 5] Cache only works partially #222

Open
mihob opened this issue Dec 29, 2024 · 1 comment
Open

[Craft 5] Cache only works partially #222

mihob opened this issue Dec 29, 2024 · 1 comment

Comments

@mihob
Copy link

mihob commented Dec 29, 2024

Describe the bug

The documentation states that Hyper loads all cached entry links in a single query. This does not seem to work.

This should probably happen at this point:

hyper/src/Hyper.php

Lines 186 to 215 in d8bb508

private function _registerCachePreload(): void
{
// Before rendering a site-based template, preload the cache for element links for significant
// performance gains. This allows us to query every Hyper link field used on the page in one
// go, rather than one at a time, for each field.
Event::on(Application::class, Application::EVENT_INIT, function() {
// When rendering a page, do a single Hyper cache query for all Hyper fields on the page.
Event::on(View::class, View::EVENT_BEFORE_RENDER_PAGE_TEMPLATE, function(Event $event) {
if (!Craft::$app->getRequest()->getIsSiteRequest()) {
return;
}
if (Craft::$app->getResponse()->getIsOk()) {
Hyper::$plugin->getElementCache()->preloadCache();
}
});
// For every element that is populated (on the front-end), record it in our render cache for Hyper.
// We'll use this to check against any element-link Hyper links that refer to _this_ element being recorded.
Event::on(ElementQuery::class, ElementQuery::EVENT_AFTER_POPULATE_ELEMENT, function(PopulateElementEvent $event) {
if (!Craft::$app->getRequest()->getIsSiteRequest()) {
return;
}
if (Craft::$app->getResponse()->getIsOk() && $event->element->id) {
Hyper::$plugin->getElementCache()->addToRenderCache($event->element->id, $event->element->siteId);
}
});
});
}

However, almost all elements are loaded after the View::EVENT_BEFORE_RENDER_PAGE_TEMPLATE event, as they are only requested in the template during rendering.

The only element that can be preloaded (if it is linked) is the entry itself whose template is currently being rendered, as this is already loaded beforehand.

Another problem is that the hyper cache is only created when elements with hyper fields are saved. If the cache is now emptied, it is only rebuilt if the corresponding elements are saved again. In the worst case, this never happens again and you don't benefit from caching at all. Perhaps you should consider a warm-up strategy here.

Steps to reproduce

Craft CMS version

5.5.7

Plugin version

2.2.2

Multi-site?

YES

Additional context

No response

@engram-design
Copy link
Member

The way that this is supposed to work, is that when populating an element (any element, not just the one you might be on), it's added to a cache for Hyper to use. This is used rather than querying the element again when trying to render an element-based Hyper link. We figure if you're using a linked-to element in say your navigation, which is run through the ElementQuery::EVENT_AFTER_POPULATE_ELEMENT event, Hyper might as well record that populated element for its own use when rendering that element's link.

Happy to look at this again, but last I checked this was working correctly.

As for the warming strategy, that's correct that there technically isn't one at the moment, but more than happy to introduce a console command to prep this. An un-cached element isn't exactly a massive performance hit, but it would be if it was never cached. For example, in my tests, it really only equated to a few seconds for a few dozen Hyper links on the page when un-cached, and that's down to a few milliseconds when cached after the first hit of a template.

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

No branches or pull requests

2 participants