a-ok Posted April 16, 2018 Share Posted April 16, 2018 Hi everyone I’m super close on launching a site I have been working on for a while but upon some final testing the TTFB on the site is super slow... like 6s slow which is madness. The site uses a lot of page queries and includes but apart from that it’s generally pretty fast – the load times after TTFB are fine. I’m wondering about a few things... 1. ProCache – this works amazingly well when enabled but of course each page has to be cached first and if the TTFB on each is slow then do you think it’s a redundant move? Is there a way to cache the pages without visiting each one? And do you think if a page is saved the default should be to empty the cache for the whole site? Be nice to get some feelings on best practice for this. 2. I use a lot of includes (.inc) in my templates as I try to build everything quite modular. Is there a better way to do this (render?) or is this generally fine? 3. Template cache – would this help with TTFB or rather the issue is with the MySQL pages queries so template caching wouldn’t help with this. I’m a little confused on template caching... 3. Markup cache – could this be used for improving TTFB DB queries or not? Thanks everyone... just keen for a bit of discussion and best practice on this. Link to comment Share on other sites More sharing options...
Sergio Posted April 17, 2018 Share Posted April 17, 2018 What's the TTFB of a procached version of a page X (a complex one)? I think template cache will not get you any advantage over ProCache, but MarkupCache will as you can cache parts of the page before ProCache kicks in! Use markup cache for blocks of code that do complex queries or when querying multiple pages. Basic example: A website has hundreds of podcast episodes. You can cache a count of these episodes so you don't need to query it when the page cache is cleared in ProCache. $template = $templates->get("podcasts"); //episodes $all_episodes_count = $cache->get("all_episodes_count", $template, function($page) { return $page->NumChildren(true); }); $view->total_episodes = $all_episodes_count; The "all_episodes_count" cache file will only be cleared when a new page is created with the template "podcasts". 2 Link to comment Share on other sites More sharing options...
a-ok Posted April 17, 2018 Author Share Posted April 17, 2018 6 hours ago, Sergio said: What's the TTFB of a procached version of a page X (a complex one)? 81ms 6 hours ago, Sergio said: Use markup cache for blocks of code that do complex queries or when querying multiple pages. Ah yes I was reading about WireCache... is it possible to declare more than one template in the get statement? $template = $templates->get("events-detail|guides-detail"); // But this of course only grabs the first $articles = $cache->get("wtg", $template, function($pages) { return $pages->find("template=events-detail|guides-detail, sort=sort"); }); Thanks for your help! Link to comment Share on other sites More sharing options...
a-ok Posted April 17, 2018 Author Share Posted April 17, 2018 Also this seems to be working but is this all correct? $eventsDetailTemplate = $templates->get("events-detail"); $wtgDetailTemplate = $templates->get("where-to-go-detail"); $mtlDetailTemplate = $templates->get("meet-the-locals-detail"); $related_events = $cache->get("relatedEvents", $eventsDetailTemplate, function($pages, $page) { return $pages->find("template=events-detail, id!=$page, location_venue!=$page, tags=$page->tags, events_detail_dates_final_date>=today, sort=random"); }); $related_wtg = $cache->get("relatedWTG", $wtgDetailTemplate, function($pages, $page) { return $pages->find("template=where-to-go-detail, id!=$page, tags=$page->tags, sort=random"); }); $related_mtl = $cache->get("relatedMTL", $mtlDetailTemplate, function($pages, $page) { return $pages->find("template=meet-the-locals-detail, id!=$page, tags=$page->tags, sort=random"); }); $related = $related_events->import($related_wtg)->import($related_mtl); $related->sort('random')->filter("limit=4"); Link to comment Share on other sites More sharing options...
cstevensjr Posted April 17, 2018 Share Posted April 17, 2018 It's great that you are actively working to improve things on your website. I would also advise you to take a look at the following linked article for other things to look out for: https://blog.ezoic.com/ttfb-shouldnt-matter-test-this-instead-for-pagespeed/ Best Regards, Charles 1 Link to comment Share on other sites More sharing options...
Robin S Posted April 17, 2018 Share Posted April 17, 2018 (edited) 13 hours ago, oma said: The site uses a lot of page queries It's this part that probably has the most impact on performance. 1 hour ago, oma said: Also this seems to be working but is this all correct? $eventsDetailTemplate = $templates->get("events-detail"); $wtgDetailTemplate = $templates->get("where-to-go-detail"); $mtlDetailTemplate = $templates->get("meet-the-locals-detail"); $related_events = $cache->get("relatedEvents", $eventsDetailTemplate, function($pages, $page) { return $pages->find("template=events-detail, id!=$page, location_venue!=$page, tags=$page->tags, events_detail_dates_final_date>=today, sort=random"); }); $related_wtg = $cache->get("relatedWTG", $wtgDetailTemplate, function($pages, $page) { return $pages->find("template=where-to-go-detail, id!=$page, tags=$page->tags, sort=random"); }); $related_mtl = $cache->get("relatedMTL", $mtlDetailTemplate, function($pages, $page) { return $pages->find("template=meet-the-locals-detail, id!=$page, tags=$page->tags, sort=random"); }); $related = $related_events->import($related_wtg)->import($related_mtl); $related->sort('random')->filter("limit=4"); If that is just to find four random items it could be done a lot more efficiently as: $related = $pages->find("id!=$page, tags=$page->tags, (template=where-to-go-detail|meet-the-locals-detail), (template=events-detail, location_venue!=$page, events_detail_dates_final_date>=today), sort=random, limit=4"); When you are wanting a specific number of results, wherever possible you should do that via a limit in the database query i.e. in the $pages->find() selector. Edited April 17, 2018 by Robin S Corrected $pages typo. 3 Link to comment Share on other sites More sharing options...
a-ok Posted April 17, 2018 Author Share Posted April 17, 2018 Thanks for your help, everyone. ProCache is working pretty well – it's just that initial load per page (before it's cached) that's causing me a few problems as that initial load is slow. I have about 3 $pages->find() queries on one of my pages where the initial load is slow – each of them querying about 150 pages. This would cause such slow initial load, right? Link to comment Share on other sites More sharing options...
a-ok Posted April 17, 2018 Author Share Posted April 17, 2018 Also if anyone has any suggestions on how to use WireCache $cache with multiple templates? $articles = $pages->find("template=where-to-go-detail|our-guides-detail, sort=sort"); The below doesn't work and returns the following error (which I guess is because I'm using $templates->find() rather than $templates->get() and the $cache expected a single template? PHP Notice: Object of class ProcessWire\TemplatesArray could not be converted to int in $template = $templates->find("name=where-to-go-detail|our-guides-detail"); $articles = $cache->get("wtg", $template, function($pages) { return $pages->find("template=where-to-go-detail|our-guides-detail, sort=sort"); }); Link to comment Share on other sites More sharing options...
Sergio Posted April 17, 2018 Share Posted April 17, 2018 53 minutes ago, oma said: Also if anyone has any suggestions on how to use WireCache $cache with multiple templates I never used this approach for more than one template, but you can also use the $expire parameter: $all_matches = $cache->save('all_articles', $pages->find("template=where-to-go-detail|our-guides-detail, sort=sort"), $expire = 432000); //week Link to comment Share on other sites More sharing options...
a-ok Posted April 17, 2018 Author Share Posted April 17, 2018 5 minutes ago, Sergio said: I never used this approach for more than one template, but you can also use the $expire parameter: Thanks, Sergio but I was wanting to do a check if a page using either the template where-to-go-detail or our-guides-detail is updated to reset the cache... whereas you can seem to only check one template. Link to comment Share on other sites More sharing options...
Robin S Posted April 17, 2018 Share Posted April 17, 2018 8 hours ago, oma said: I was wanting to do a check if a page using either the template where-to-go-detail or our-guides-detail is updated to reset the cache See this blog post where it talks about using a selector string as the "expires" argument. But before you go too far into WireCache as a solution for your problem I recommend going through your PageFinder queries ($pages->find(), $page->children(), etc) to see if they can be optimised. You might find you don't need WireCache then - for example, if you change to the query I suggested in my previous post you probably wouldn't need to cache it. 9 hours ago, oma said: I have about 3 $pages->find() queries on one of my pages where the initial load is slow – each of them querying about 150 pages. It's not so much how many pages you are querying that matters, it's how many pages your query is returning. If each of your 3 queries returns 150 pages then this is not ideal unless you are actually using 450 pages in your markup somehow. Your aim should be to return no more pages that you are actually going to use. Also try to avoid multiple PageFinder queries if the same result can be achieved in one query (as demonstrated in my previous post). Link to comment Share on other sites More sharing options...
a-ok Posted April 17, 2018 Author Share Posted April 17, 2018 Thanks for this, Robin. One query is returning 60+ results... no pagination. As soon as I add a limit to it (18) it’s a lot faster. Guess that’s mainly it, right? Interesting to know re the wireCache... but apart from the odd few queries that I will make more efficient I guess it’s down to what’s being returned (rather than queried as you say). Link to comment Share on other sites More sharing options...
a-ok Posted April 17, 2018 Author Share Posted April 17, 2018 What about $pages->findMany() – could that work? https://processwire.com/api/ref/pages/find-many/ Link to comment Share on other sites More sharing options...
Gideon So Posted April 18, 2018 Share Posted April 18, 2018 Hi @oma, 9 minutes ago, oma said: What about $pages->findMany() – could that work? https://processwire.com/api/ref/pages/find-many/ This works faster. Gideon Link to comment Share on other sites More sharing options...
gebeer Posted April 18, 2018 Share Posted April 18, 2018 12 hours ago, oma said: Thanks, Sergio but I was wanting to do a check if a page using either the template where-to-go-detail or our-guides-detail is updated to reset the cache... whereas you can seem to only check one template. You can use a hook in ready.php to delete cache on save of pages // delete caches when pages are created, saved or moved around wire()->addHookAfter('Pages::save', function(Hookevent $event) { $page = $event->arguments(0); // do nothing on admin pages if($page->template == 'admin') return; // delete cache for templates if($page->template == 'where-to-go-detail' || $page->template == 'our-guides-detail') { $this->cache->delete('wtg'); // here you could add logic to rebuild the cache } }); 5 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now