3215 Posts in 848 Topics by 811 members
|Go to End|
11 October 2012 at 5:22pm
I've built a site (in SS 2.4.7) for a client to use as a knowledgebase and, as such, it contains a vast number of pages with much more hierarchical depth than your average site.
We've been having speed issues which may be a result of hosting on Dreamhost, but I've noticed that the menu system seems to affect the page load speed greatly.
A page with the menu switched on takes about 6-8 seconds to load, but the same page with the menu switched off takes about 2 seconds.
I'm concerned this means each page load is having to dig the whole content of every page out of the database so it can populate the menu with all the Titles of every sub page!
The menu is a fairly standard 'Suckerfish' style flyout, with about six levels of depth, and I've attached my template code for you to check out. Please let me know if you spot anything dodgy in there that could help.
I wonder if there might be a way to delay the populating of deeper levels of the menu until someone actually hovers over the menu?
Any advice on dealing with this kind of site in SS will be much appreciated.
BTW, am getting YSlow scores of about 83-94 so the site overall should be pretty speedy I think.
13 October 2012 at 12:19am Last edited: 13 October 2012 12:42am
1- Overload the getMenu method of your controller and use custom SQL to fetch only the columns you need. Or write a new function like getSimpleMenu (probably a better idea).
3- Use partial or total caching, read:
Method #1 is not terrible and you can do it along side #3 for even better performance. Method #2 is a bad idea in that it requires a lot of effort and any gains come at the expense of breaching the mvc model. #3 is quicker to implement and will likely give the largest performance boost on average.
In this instance you would wrap your menu with this:
<% cached 'navigation', List(Page).max(LastEdited) %>***
<% cached 'navigation', Aggregate(Page).Max(LastEdited) %>
<% end_cached %>
*** The struck out line is for 3.0, my bad.
Now I haven't tried this, but according to the page at the link I posted, the section wrapped in this will be cached until any page on the site is edited. So if after you are done making edits you refresh a page on your site with the navigation, your visitors will always get a cached copy of the menu.
Alternatively you can cache entire pages. You can read up on that here:
15 October 2012 at 9:20am
Thanks Kaanumi for your fantastic response. Great to get such excellent detail around possible solutions, their pros and cons, and how they'll work rather than just a simple "Do this..." with no explanation.
I'll take a look at the links in your posts and come back with any questions and the results from my implementation.
Thanks once again!
15 October 2012 at 4:46pm
Success! Partial-caching is now my best friend! By caching my menus I've reduced page load times from 8-10 seconds down to 2-5 seconds.
Ran into a few gotchas though:
1) If a <% require %> tag is inside the <% cache %> tag, it ceases to be called once the content is cached. I had a CSS file in this situation and my menu would completely restyle itself once it was cached, defaulting to another CSS file further up the chain.
2) I can't use the same menu for the Secure and Public sections of the site. If I do, the public end up seeing the Secure pages listed in their menu, though they can't access them of course.
3) I've had to tweak my CSS as, for some reason, the a.Section and a.Current tags seem to cache sometimes too, resulting in the menu continuing to display a previously visited page as the Current page. This seems a bit intermittent so I'm confused, but I've simply disabled my styling for Current pages so it won't affect end users.
Thanks once again Kaanumi for pointing me towards the partial-caching feature - it has saved Silverstripe from being dumped by the client on this project!
24 October 2012 at 8:36pm
2) Use the CurrentMember flag as part of your cache key.
3) Add ID as part of the cache key
<% cached 'Menu', Aggregate(SiteTree).Max(LastEdited), ID, CurrentMember.ID %>
20 November 2012 at 11:17am
Thanks for the CurrentMember.ID tip Will, that should fix the anomalies for me. Unfortnately I'm still getting some issues:
If I log in with one user, then log out and log back in with a second user who has different page view permissions, the second user still sees the menu as it appeared to the first user, including items that should be restricted. (If they click the items they are told they don't have access.)
Is there something else I need to do to force the menu to render according the current user's page access rights?
Could it be caused by the fact that the cached menus are all in Includes, not directly in any page template?
|Go to Top|