Inside TYPO3

Need for speed: TYPO3 Website-Caching

Caching is always a tricky thing and a good caching strategy always depends on the use cases of the website. 

Website Caching Levels

Of course there are tons of possible ways to cache a content on a website - I only want to look at the most promising cache levels:

  1. Cache-Control Headers: If your website sends proper "Cache-Control: public" HTTP Headers together with a proper expire that's perfect for caching: Your browser will store the website in its internal cache - and there is nothing that could be faster than this.
  2. Varnish: Varnish is a "web application accelerator" - its build to cache content based on powerful configurations. (It also supports loadbalancing and failover handling)
  3. TYPO3 Page Cache: TYPO3 caching framework is very flexible and should be used of course. It can handle Full-page cache based on parameters, logins and conditions. It also supports dynamic marker replacement and dynamic content parts (USER_INT).
  4. Application Caches (Feature specific caches in our application logic)

 

How dynamic is my website?

The first thing to consider is, if your website looks different based on certain criterias. For example (from easy to hard to solve):

  1. based on time (news articles)
  2. based on a login (e.g. after login I see personalized informations)
  3. based on the user (even without login - e.g. based on location, cookie informations, browser history...)

 

Decide on a cache strategie

1 Use Cache-Control where possible

The best you can do is allow client side caching. In TYPO3 this is pretty easy, you just need to set:

config.sendCacheHeaders=1

The precondition is, that the page is cacheable (no user INT).

TYPO3 then sends proper Cache-Control Headers.The Expire time is depending on the settings in the page: You can control the expire time for all pages in the page properties (Cache expire). (Default is always one day or you set the default with config.cache_period ). Also you can set the expire to end at midnight with:

config.cache_clearAtMidnight =1 

Problem 1: "USER_INT":

There are a lot of plugins, that are USER_INT. Some of them could be USER if done in a proper way:

  • is cHash used correct to have different cacheentries based on parameters?
  • Does the plugin only show dynamic content after login? Then this is a nice solution:
    plugin.tx_felogin_pi1 = USER 
    [usergroup = *]
    plugin.tx_felogin_pi1 = USER_INT
    [global]
  • Does the plugin only show dynamic content if a certain parameter is set? Then this is a nice solution:

    [globalVar = GP:aoe_solr|sword=]
      plugin.aoe_solr=USER
    [else]
       plugin.aoe_solr=USER_INT
    [global]

 

Also its always a possible solution to let the client (browser) load the dynamic parts via ajax after dom ready. This is a nice solution - since the user immediately sees the website - and still has dynamic informations. This is for example the case for the login box used on the typo3.org relaunch.

Problem 2: Login and User specific content

If your page offers a login, and the page looks different after login you have problems with Cache-Control headers: When the urls to the pages stay the same, your browser might have a cached page and therefore will not ask for a new one that includes the changed content. So if you still want to use Cache-Headers, you have this possibilities

  • Use ajax calls to add dynamic content (same like above). Especially wen you have a highly personalized website with a lot of user specific content there are solutions around, that use search technologies to display dynamic user-specific content. (e.g. the searchperience recommendation engine and widget features)
  • or take care that the urls look different after login (to force the client to load new content):
    • The best is to switch from http to https after login. You can then tell TYPO3 not to send Cache-Control Headers in HTTPS:  (the condition depends on the server - also if using varnish you  need to find another way of detecting https )

      [globalString = _SERVER|HTTPS=on]
        config.sendCacheHeaders=0
      [global]

    • You can also simply add an additional parameter to the URLs after login, and dont send Cache Headers if that parameter exists ( config.linkVars=login )

2. Use Varnish

If you only have Cache-Headers, TYPO3 still needs to deliver the page for every new user. By adding another layer of cache even this can be avoided.

Fabrizio wrote a nice blog article on setting up Nginx + Varnish: www.fabrizio-branca.de/nginx-varnish-apache-magento-typo3.html

Problem 1: Cookies

Cookies might be a problem. A typical Varnish configuration will not cache if the server sends cookies. And TYPO3 per default always sends cookies, because you need this for the login. There are several solutions:

  • If you dont need login you simple may drop the cookies in varnish or set this TYPO3 setting:
    $TYPO3_CONF_VARS['FE']['dontSetCookie'] = TRUE;
  • Better is to tell TYPO3 only to send a cookie if there is a valid user logged in. This can be done by installing some of the extensions (moc_varnish or cacheinfo). You may want to look at forge.typo3.org/projects/show/extension-cacheinfo , since this extension not only modifies the cookie behavior, but also adds several X-T3Cache* HTTP Headers that helps a lot...

Problem 2: rsaauth and PHPSESSION cookie

If you dont use https for your frontend login, TYPO3 offers a way to still secure your login. This is done with the help of the extension "rsaauth" and can be activated by setting the securityLevel to "rsa". However this extension is not functional with client side caching - so please use https and deactivate rsa...

A recommended login configuration is:

$TYPO3_CONF_VARS['FE']['loginSecurityLevel'] = 'normal';

and have "saltedpasswd" installed and activated in extension settings.

(For the backend you should use lockSLL )

TYPO3 might still send PHPSESSION cookies - they can be dropped in varnish. ( see also Bug: forge.typo3.org/issues/29927 )

ESI - Edge Side Includes?

ESI is a technique from varnish to get dynamic content in a cached page. The extension moc_varnish has support for this (rewriting USER_INT to ESI Includes).

But in fact I think ESI don't has  advantages:

  • Varnish needs to wait till all ESI calls are finished before it can deliver the page. That means the page deliver time is much lower compared to a page without ESI.
  • The same could be achieved using ajax calls: Then the user gets the page asap and a single ajax call can be done (instead of multiple ESI calls). I think for most websites that require something like this it's ok to require javascript support.

 

 

 

 

blog comments powered by Disqus
blogroll