small idea - speeding up templates by calling methods only once

52 views
Skip to first unread message

Nicolaas Thiemen Francken - Sunny Side Up

unread,
Apr 23, 2015, 4:59:30 AM4/23/15
to silverstripe-dev
Hi

A few weeks ago I wrote about checking for a valid ID value before running the byID method all the way to the Database Layer (i.e. if the ID is zero then there is really no point in doing the DB call). 

I now have another question about speeding up Silverstripe.  I noticed that if I write the following in my template:

$MyMethod
$MyMethod
$MyMethod
$MyMethod
$MyMethod

and place a debug::log in the MyMethod method the Page_Controller that I get a bunch of entries in my debug file (five entries).  I am wondering - is it really necessary for the template to collect the value from the method five times.  

I realise that collecting the value only once can have significant consequences (i.e. it is a 4.0 or 5.0 sort of change) and that it may be very hard to change the framework core. This is exactly the reason it would be good to think about this now. 

I am particular thinking here where you do stuff like

<% if MyDemandingMethod %>
  <% loop DemandingMethod %>

I presume the DemandingMethod would also be called twice.

I know that partial caching (http://doc.silverstripe.org/en/developer_guides/performance/partial_caching) and many other tricks are all methods to speed up templates - but the idea above could also help a little? 

Both the byID and the template one here will save milliseconds if that, but they are also extremely common and that is where it is going to make a difference - perhaps?

Nicolaas
PS a fascinating thing that happened in running the test for this little write up was that the debug log actually showed a ton more calls, made over several seconds, than the expected five... I am like - wow - someone is accessing my localhost and viewing the same page ;-) before I realised that on my localhost there were about ten images that returned 404. Thus, a call to a 404 image also called the same $MyMethod the same five times for each missing jpg file. 


Jonathon Menz

unread,
Apr 23, 2015, 12:07:36 PM4/23/15
to silverst...@googlegroups.com, n...@sunnysideup.co.nz
Hi Nicolaas, you would probably love a great little trick called Cached Method Calls that may be completely undocumented (on official channels at least). Just add an underscore to the start of the method name and it should only be called once from your templates.

Jonathon Menz

unread,
Apr 23, 2015, 12:19:40 PM4/23/15
to silverst...@googlegroups.com, n...@sunnysideup.co.nz
Actually I don't think that trick is working (or necessary) anymore - apparently all methods should be cached when accessed from templates - see http://doc.silverstripe.org/en/developer_guides/templates/caching/ I tested and this is working properly for me. Not sure why you'd be getting different results?

Stevie Mayhew

unread,
Apr 23, 2015, 2:49:04 PM4/23/15
to silverst...@googlegroups.com, n...@sunnysideup.co.nz
This is the case now Jono - I couldn't replicate this either even when doing intentionally silly things like running a counter :)

Patrick Nelson

unread,
Apr 23, 2015, 3:09:32 PM4/23/15
to silverst...@googlegroups.com
I thought that, by default, all method calls to objects are cached? I know it's mentioned all over the place, e.g. http://doc.silverstripe.org/en/developer_guides/templates/caching/

And in response to this:

PS a fascinating thing that happened in running the test for this little write up was that the debug log actually showed a ton more calls, made over several seconds, than the expected five... I am like - wow - someone is accessing my localhost and viewing the same page ;-) before I realised that on my localhost there were about ten images that returned 404. Thus, a call to a 404 image also called the same $MyMethod the same five times for each missing jpg file. 

This is most likely why you're seeing logs showing multiple calls to a method which should be getting cached and run only once per page view. Have you tried loading that page in Chrome using the "view-source:" handler (just view the source, reload and watch the log). If you try it that way, chrome will not be attempting to load additional resources and thus no 404 and therefore no additional hits to that page for each missing resource. Which is still odd because I thought the 404 page was pre-generated and cached as well (down the rabbit hole we go...)


--
You received this message because you are subscribed to the Google Groups "SilverStripe Core Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to silverstripe-d...@googlegroups.com.
To post to this group, send email to silverst...@googlegroups.com.
Visit this group at http://groups.google.com/group/silverstripe-dev.
For more options, visit https://groups.google.com/d/optout.

Jonathon Menz

unread,
Apr 23, 2015, 3:30:50 PM4/23/15
to silverst...@googlegroups.com
Coming down the rabbit hole with you Patrick... Out of the box, 404 pages are dynamically generated, which is a potential performance issue. 500 error pages are served statically because they have to be (fatal error -> php can't continue). Static 404 and 500 error files are generated when you save error pages in the CMS and during a dev/build but only if they're missing. This is a pretty bad setup I think which I've been trying to draw attention to for a while as it leads to stale and broken static error files, and having error pages in the site tree is confusing for CMS users also. Vote for change here if you like! https://silverstripe.uservoice.com/forums/251266-new-features/suggestions/6843397-overhaul-error-page-management

Patrick Nelson

unread,
Apr 23, 2015, 3:40:00 PM4/23/15
to silverst...@googlegroups.com
Well, the odd part to me was just that it's possible that the 404 he was getting was dynamically generated (a theory explaining the multiple log entries). The solution in this case would simply be to go into his 404 error page and click "Save & Publish" and done. That and actually fix the 404 problem in the first place. I have encountered some issues with not originally realizing that the 404 page was not always dynamic (but instead static) which was just yet another esoteric component of SS that I had to learn and, in this case, grow to appreciate. I only had an issue with content being generated per-user, cached in the 404/500 error page and then being spat out to unrelated users in the form of that static page - but that's a dev issue, not a system issue per se :)

Jonathon Menz

unread,
Apr 23, 2015, 3:49:45 PM4/23/15
to silverst...@googlegroups.com
I agree with your diagnosis about the multiple log entries, but I don't think saving and publishing the 404 error page in the CMS will fix that - I tested it just now and I'm still getting a dynamic 404 page. On a regular SilverStripe install straight out of the box I don't think that static 404 page will ever be displayed to visitors... Are you able to test and confirm otherwise?

Patrick Nelson

unread,
Apr 23, 2015, 4:09:29 PM4/23/15
to silverst...@googlegroups.com
I tested it, you're right -- the ErrorDocument handler is there but mod_rewrite is overriding that by proxy of RewriteCond's in place to route it through the CMS and, based on my testing, it isn't itself then using the statically generated version but dynamically generating that document before outputting it. If Apache encounters an HTTP 404 that isn't somehow handled by the framework, it will utilize the static version but I'm not sure how that could happen (not saying it can't, it depends on what you end up doing to the boilerplate .htaccess file I suppose).

Anyway -- more support for my original theory I suppose.

Reply all
Reply to author
Forward
0 new messages