Contao news

Read the official Contao announcements.

Optimizing Contao for Google Page Speed

by Leo Feyer – From practice

At least since Google has announced that the speed of a website is one of the criteria for its page rank, people care a lot about optimizing their web pages. This article will show you how to "tune" Contao to get a high page speed score.

Targeting regular websites

I assume that most of you have installed Contao on a shared hosting account, so I will not bother you with load balancers, content delivery networks or op-code caches, which surely are powerful tools to optimize the page speed but might be a little oversized for normal websites. We rather want to know to which extend you can optimize the page speed score with the onboard features of Contao and a little .htaccess magic (which means making use of Apache features such as mod_rewrite).

What you need

Basically, you need two things: Firefox with the Firebug and the Google Page Speed plugin and an Apache web server which supports mod_deflate, mod_headers, mod_expires and mod_rewrite. If your server does not meet those requirements, check out the iNet Robots hosting plans or the Contao hosting partners.

About the perfect score

An optimal page speed score would be 100 out of 100 points, but even Google itself only scores 96. This is because not all suggestions make sense and not all of them can be implemented in practice. For example, there is a "use efficient CSS selectors" notice on google.com as well as on contao.org and most likely also on your website. #mainmenu li.active span surely looks like an inefficient selector to a machine, but how do you tell your computer that it is more important to get the cross-browser CSS drop-down menu to actually work in all browsers than to use the most efficient selectors? Of course you are supposed to try to get both, but it is important to realize why in most of the cases you will not.

Contao back end settings

In the "Global configuration" section in the back end settings, you should enable GZip compression. This will make Contao compress the pages before they are sent to the browser. Also, while you are in the back end settings module, you should enable URL rewriting. Although this is not a page speed related setting, it will help a lot to improve your page rank.

Then switch to the themes manager and edit your page layouts. In the "Style sheets" section, there is a very important new feature called "Aggregate style sheets", which has been added in Contao 2.9. It will make Contao combine all style sheets into one single file, which greatly improves the loading time of your website - especially if you have a lot of style sheets. Also make sure to check "Skip files/tinymce.css" if you are not using the TinyMCE style sheet.

Another important speed tuning option is hidden in the "Experts settings" section. Find the "MooTools source" menu and choose "Load from googleapis.com". This will make Contao load the MooTools core script from the Google content delivery network instead of your server.

This is all you need to do in the Contao back end. Next let us take a look at the Apache configuration.

Tuning the Apache configuration

The easiest way to modify the Apache configuration is to use a .htaccess file. You will find all the code described below in the .htaccess.default file of Contao 2.9.1. However, do not just rename the file but look at the default settings and adjust them to fit your individual needs if necessary.

Enable compression

We have already enabled compression for PHP files in the Contao back end, so the Apache server only needs to handle CSS, JavaScript and XML files. On-the-fly compression is done with mod_deflate.

<IfModule mod_deflate.c>
<FilesMatch "\.(css|js|xml)$">
SetOutputFilter DEFLATE
</FilesMatch>
</IfModule>

Specify a Vary: Accept-Encoding header

Proxy cache servers should always store both the uncompressed and the compressed version of a file, because some clients do not accept GZip compressed files. However, a lot of them will not unless there is a Vary: Accept-Encoding header, so we will make sure to send one using mod_headers.

<IfModule mod_headers.c>
<FilesMatch "\.(js|css|xml|gz)$">
Header append Vary Accept-Encoding
</FilesMatch>
</IfModule>

Leverage browser caching

Google Page Speed recommends to specify an expiration one week in the future for images, JavaScripts and CSS files, so the browser loads these resources from the local disk rather than over the network. You can easily accomplish this with mod_expires.

<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/png A604800
ExpiresByType image/gif A604800
ExpiresByType image/jpg A604800
ExpiresByType image/jpeg A604800
ExpiresByType text/javascript A604800
ExpiresByType application/x-javascript A604800
ExpiresByType text/css A604800
</IfModule>

Cracking 90 percent

So far, our tuning efforts have increased the page speed score of contao.org to 86 out of 100.

As explained above, it is not possible to use more efficient CSS selectors on contao.org or to remove the four unused format definitions for the left column and the custom layout sections from the CSS framework file. Also, we have already reduced the number of CSS and JavaScript files by combining them into as few files as possible, so the only options left to improve the page speed score would be to parallelize downloads across host names and to serve static content from a cookieless domain. Both sound a lot like using a content delivery network, which would be clearly oversized for contao.org.

But actually Google does not require you to use a CDN. It does not even require you to use a different host name, just a "cookieless domain", which might as well be a sub-domain of your domain. So I have set up the domains "st1.contao.org", "st2.contao.org" and "st3.contao.org" in the server control panel, all pointing to the same directory as "www.contao.org". To prevent duplicate content, I have added the following lines to the .htaccess file in the Contao root directory:

##
# Explicitly send a 404 header if a file on st[0-9].contao.org is not
# found. This will prevent the start page (empty URL) from being loaded.
##
RewriteCond %{HTTP_HOST} ^st[0-9]\.contao\.org [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* - [R=404,L]

##
# Do not dispatch dynamic resources via st[0-9].contao.org.
##
RewriteCond %{HTTP_HOST} ^st[0-9]\.contao\.org [NC]
RewriteCond %{REQUEST_FILENAME} \.(php|html)$
RewriteRule .* - [R=404,L]

Thanks to the code above, it is not possible to request PHP and HTML files through the sub-domains. It is, however, possible to request static files like style sheets, images or PDFs. And the domains are "cookieless", just like Google wants it. Except …

Google Analytics is raining on our parade

By default, the Google Analytics cookies are valid for a domain and all its sub-domains (".contao.org" in our case). Of course, this also includes our static domains "st[1-3].contao.org". Luckily, this behaviour can be modified in the moo_analytics template.

<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-XXXXXXX-X']);
_gaq.push(['_setDomainName', 'www.contao.org']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>

Making Contao use the sub-domains

This is indeed the crunch point of our little "hack". I have solved it on contao.org by adding a simple output filter using the outputFrontendTemplate hook. We might as well add this as a feature in Contao 2.10 if it turns out to be helpful. But for now, you have to use the hook.

Reaping the fruit of our labor

Et voilà, after activating the output filter, the page speed score of this page (the one your are currently viewing) has increased to 96 of 100. The page speed score on the start page of contao.org is a little less, because most of the imagery is included via CSS and thus loads through the same sub-domain as the style sheet itself (st2 instead of st1). It could be fixed by using absolute URLs in the style sheets, though.

Of course, this tuning measure does not reduce the number of requests that are sent to your server and is therefore not suitable to reduce the server load or traffic. It is just meant to optimize the page speed - and it succeeds in doing so :)

Show all news

Comments

Comment by Kamil Kuzminski |

Awesome article! Good job Leo!

Comment by Tsarma |

Nice tips, I'll implement this in my new projects. thanks a lot Leo and Team

Comment by Matthijs Brands |

Thank you for the tips! Especially with the sub-domains. I tried to implement this a few times, never quite got it. Hope to see this implemented default in typolight. Maybe with the possibility to use different domains for every site.

Comment by Bright nation |

Hi Leo,
thank you for this post. With minimal effort my page speed was boosted 80 -> 92.
Antonio

Comment by Alex Stadler |

Hey There,

Great article! Thanks a lot for it!
I just got a problem, or better I should say: I don't know how to use the "simple output filter using the outputFrontendTemplate hook" you mentioned. Where do I have to add those lines?
Could you please give me a hint?

Best regards, Alex!

Comment by Eric Vantroeyen |

This technique works well, but google page speed (on line http://pagespeed.googlelabs.com) detects a duplicate content with the jpeg images from st1 and www. How can it be avoided? How could be defered the parsing of javascipt?

Regards
Eric

Comment by Frank |

I run a domain name and web hosting company, and even I have benefited from this article regarding the performance of our website. I’m very thankful for people who put time and effort into educating others like this.

Thank you, and I've booked this page for others who need tips!

Comment by Amit Jivani |

Really fantastic set of information...

Comment by Catalin Nistor |

Great article! Thanks a lot!

Comment by Shailendra Mahanande |

This is nice article
Very very helpful
Thanks a lot...

Add a comment

What is the sum of 2 and 5?