Jump to content

Caching a highly dynamic site


kyle
 Share

Recommended Posts

I am working on a little project that is highly dynamic.  It relies heavily on forms and sessions.  What are some caching options available?  I have looked at the MarkupCache and the ProCache module.  Should I use template caching?  The site is a little bit like the Skyscrapers example site in the way it lists the pages, but pages are constantly being added.  I have APC enabled for the site and I run it through cloudflare.  Anything else I can do to keep it fast?

Link to comment
Share on other sites

I would think you've got all the 'native' PW options down. If it's a 'little' project i would first see how things perform without any caching. Also remember the usual stuff for pagespeed optimizations, this can greatly impact the feeling you get when visiting a site.

If you do want/need caching it's hard to say which one from your ts; this depends on the structure of the project and exactly what kind of dynamic stuff there is. For template caching there are also a couple of different cache expiration options; which may or may nor work for you in this particular project.

Performance-wise i think it would be: ProCache > template cache > MarkupCache.

Teppo's got a nice article on PW caching on his blog: http://www.flamingruby.com/blog/processwire-caching-explained/

Of course there's lot's more you can do (memcached, varnish etc.) but this is not directly related to PW, and probably overkill.
 

  • Like 2
Link to comment
Share on other sites

@SiNNuT thanks for the link.  The target of the site for right now is ~30,000 people, and I really think that about 1/3 of the people will regularly use it.

The site is classifieds service.  So there are always new posts.  It is organized like this:

> Location

    >Category

        >Ads

    >Category

        >Ads

    >Category

        >Ads

I gave APC a about 700M of memory to use so hopefully that helps out.  I ran it though a blitz stress test and it started off really well but after about 1,000 hits it starts to time out.

Link to comment
Share on other sites

Without knowing the blitz test it's hard to tell what those results actually mean.

But if the main part of the dynamics is that ads (pages) are being added very regularly i would think template caching or even more performant, ProCache would be very good options and probably very easy to implement.

Link to comment
Share on other sites

Template caching and ProCache are pretty similar. Procache is more effective, since it works on .htaccess rewrites. Cached pageviews doesn't even touch PHP or MySQL, just pure HTML served by Apache directly. Template caching makes one simple check (PHP & MySQL) to see whether to serve cached or noncached content.

Some simple speed comparison is available here: http://processwire.com/api/modules/procache/

Link to comment
Share on other sites

It is pretty amazing how much of a difference caching in general makes.  I ended up enabling template caching for everything but the register, login, and account management page and plan to add procache when I get money.

edit: I had the caching enabled but it prevented people from using the frontend login form

Link to comment
Share on other sites

I personally do what Apeisa suggested: use ProCache with occasional bits of MarkupCache where it makes sense (like caching renders of large <select> lists or that sort of stuff). Though keep in mind, MarkupCache is only used when ProCache isn't. So MarkupCache is only there to speed up some elements in non-cached page renders. Many sites simply don't have anything that benefits form MarkupCache, so don't make it part of your strategy to use MarkupCache until you find a need for it.

ProCache won't be used on any POST requests, so that it doesn't interfere with front-end forms, logins, etc. (Template cache can also be configured to do this). I also usually configure ProCache to not run when specific GET variables are present (or all GET variables, if preferred). This enables you to consider any request containing GET or POST variables as truly dynamic (never cached), and any requests without them as potentially cached requests.

ProCache can also cache requests that use URL segments. As a result, in order to increase the pool of potentially cached pages, I will use URL segments instead of GET variables for some high volume requests. 

Given all this, my suggestion is to use ProCache to cache the default view of all pages where possible. But consider any requests containing POST/GET variables as non-cached, dynamic requests. And if you have any components in your page that are slow to render (like a giant navigation tree or something) then use MarkupCache with those.  If your cached pages have elements that need to change daily, hourly, every 10 minutes, etc., then set your ProCache expiration time accordingly. Using Javascript for some elements also enables you to make a cached request look dynamic. 

  • Like 2
Link to comment
Share on other sites

Last thing I want to add is that ProCache is not active when a user is logged in, meaning their requests are all dynamic. Template cache works the same, though can be configured to cache requests for logged in users. MarkupCache is always cached, and doesn't care if the user is logged in or not. 

  • Like 2
Link to comment
Share on other sites

  • 4 weeks later...

Dear Ryan and All,

I noted this statement on the cache settings in the templates:

Note that the cache is always disabled for pages where the user has edit access, regardless of what you select here.
 

The site I'm building is behind a "members" login, where everyone who logs in will spend 99% of their time

adding and editing data records in a rather complex tree system.

Each page is modular, based on the PW method of each page having its own template field set and corresponding template file.

Thus, mostly, I'm dealing with small template files that load a variety of other files via php include statements. Most of the loaded

files do various checks or operations using code that can be re-used between pages.

I haven't counted, but I think most pages will load between 10 and 20 include files, that are mostly code that relies on variables set

in the parent page.

In the last few days, I've been experiencing a slowdown. I'm not sure if it's my coding, my 1 gig VPS server,

or something else. I've looked at the template caching, etc, but my assumption (possibly incorrect) is that

because the web app is all focused on adding and editing pages (and displaying them of course), it's not feasible

to use template caching.

I'm also using a cPanel box with suPHP, and I *think* that opcode caching won't work. ?

Does anyone have any recommendations? Of course, I realize that getting a better machine with more RAM will help.

One question about a PHP upgrade: this machine uses 5.2.17. If I upgrade to PHP 5.4+, will it break any code in PW?

I noted Ryan's post on this page:

http://processwire.com/talk/topic/4280-best-server-configuration-for-processwire/

The pages tonight were loading at around 2 seconds without SSL, and around 3+ with SSL.

Thanks!

Peter

Link to comment
Share on other sites

In the last few days, I've been experiencing a slowdown. I'm not sure if it's my coding, my 1 gig VPS server,

or something else. I've looked at the template caching, etc, but my assumption (possibly incorrect) is that

because the web app is all focused on adding and editing pages (and displaying them of course), it's not feasible

to use template caching.

If the users are all editors, it's true that you won't want to use any automatic caching (and may not be able to). But you can always use MarkupCache to cache elements that you know are ok to do so. 

In your case, I would try to isolate the bottleneck. Wrap statements like this around your significant sections of code, until you track down what is causing the slowdown:

$timer = Debug::timer(); 
// .. a block of code you want to measure
$this->message(Debug::timer($timer)); 

It'll tell you how many seconds the block took to execute. If this is outside of admin context, you can replace the $this->message() with an echo or something else, anywhere that you can see the results. 

Once you find the source of the bottleneck(s), you may be able to optimize them to improve the speed. Often times there is just an inefficient block of code that can be fixed. But if that's not the case, you may want to then look at MarkupCache'ing them. 

$cache = $modules->get('MarkupCache');
$out = $cache->get('your-unique-name', 86400); // 86400=num seconds age 
if(!$out) {
  $out = SomethingThatTakesAwhile(); 
  $cache->save($out); 
}
echo $out; 
I'm also using a cPanel box with suPHP, and I *think* that opcode caching won't work. ?

I don't know about that context, but an opcode cache can be very helpful. If you can't use an opcode cache, I would make whatever changes are necessary so that you can. 

If I upgrade to PHP 5.4+, will it break any code in PW?

No PHP 5.4+ should not break anything. In fact, I think you'll find that just switching to PHP 5.4 provides a nice speed boost in itself (at least it seemed like it to me). I am running PHP 5.4+ on all of my own PW installs now. 

  • Like 3
Link to comment
Share on other sites

  • 3 months later...

I'm thinking about Caching and areas of a site where there is just ONE dynamic element to keep things fast for everyone. For example, any site that has member accounts.

What would be the possible ways of approaching this whilst still having the rest of the page cached as much as possible?

I was toying with the idea of an AJAX request to load the member-related menu items after page load. The up-side is a quick load time for the page and that you could theoretically keep using ProCache whether logged in or not (if you could configure it that way) but the downside would be a delay to loading the member-related page items.

In the background of course, you've just gone and initialized ProcessWire as part of the AJAX request, so there's no savings to be made in terms of load on the server there, but I sort of like the idea of loading the content as quickly as possible.

Another way to do it could be with an Iframe, but that feels soooo last decade ;)

The other option would just be to use MarkupCache on all sensible places on the page to keep things simple for the server when members load the page, use ProCache for guest users and make sure there's enough grunt in the server to serve pages as quickly as possible.

Any other suggestions? Or am I trying to over-optimise things do you reckon?

Link to comment
Share on other sites

Pete, the standard template cache and markup cache are pretty easy to figure out and modify. I ended up writing a module with a caching mechanism similar to template cache (stores markup by page number in a subfolder of /sites/assets/cache/). That module does other things too but my point is that in template files for a site like you describe, this lets you prepare dynamic and cachable chunks of markup separately.

The majority of the page content would be cached and the template file only has to make the dynamic part and combine the two. Usually, it's the top of the page that's dynamic (user status, links for logout, profile, etc.)  and the rest is appended to that. If you also want to use AJAX this method gives you a chance to insert Javascript for that as you put together the page.

The little bit of work that doesn't get cached tends to be very simple/fast.

Link to comment
Share on other sites

For truly dynamic pages that need to change on every request, don't use a template cache or ProCache, and instead use MarkupCache for the parts that don't often change (if you need to use a cache at all). 

No doubt, delegating things to javascript where possible is very cache friendly with template caching and ProCache. Even if you are shifting things to be ajax-loaded, the ajax requests can themselves be delivered by ProCache or template cache, perhaps just on a shorter cache time. Not to mention, the results of those ajax requests can be cached client side in cookies if needed, serving as a client-side cache that you control. But I honestly don't think most people need to get into this level of caching, unless dealing with some major traffic considerations and/or server that can't keep up with it dynamically. 

Link to comment
Share on other sites

  • 1 year later...

i wrote something about it here: https://processwire.com/talk/topic/8161-website-performance-with-processwire-nginx-and-fastcgi-cache/

as other people said before: it always depends on the audience, the type of traffic and the architecture of your site. Sticking to the thread title, caching with fastcgi_cache or ProCache is not really the right way for a "highly dynamic site". Varnish is still on my list, especially because of the Edge Side Includes.

What I think might also be a nice way to gain performance in terms of caching would be the use of memcached together with MarkupCache. That would – done right – probably give a nice speed boost.

Depending on your hosting environment you could also try Facebooks HHVM as a backend. This is a JIT-Compiler for PHP and works way more efficient than just opcode caching (although APC would already boost things up). Disadvantage is that it needs some time to "get warm", so if you only have one visitor in a while, it might not be the right thing for you.


Still: when you use Apache and have a high(er) traffic site, try ProCache first. It's only fair, as Ryan will profit from that and he deserves it :) It's not worth to completely switch infrastructure just to save a few bucks.

Link to comment
Share on other sites

i wrote something about it here: https://processwire.com/talk/topic/8161-website-performance-with-processwire-nginx-and-fastcgi-cache/

as other people said before: it always depends on the audience, the type of traffic and the architecture of your site. Sticking to the thread title, caching with fastcgi_cache or ProCache is not really the right way for a "highly dynamic site". Varnish is still on my list, especially because of the Edge Side Includes.

What I think might also be a nice way to gain performance in terms of caching would be the use of memcached together with MarkupCache. That would – done right – probably give a nice speed boost.

Depending on your hosting environment you could also try Facebooks HHVM as a backend. This is a JIT-Compiler for PHP and works way more efficient than just opcode caching (although APC would already boost things up). Disadvantage is that it needs some time to "get warm", so if you only have one visitor in a while, it might not be the right thing for you.

Still: when you use Apache and have a high(er) traffic site, try ProCache first. It's only fair, as Ryan will profit from that and he deserves it :) It's not worth to completely switch infrastructure just to save a few bucks.

do u have any experience to make pw to work with varnish ?

Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...