Moresoda's lead developer Christopher Imrie explains how to streamline your ExpressionEngine sites and shares some practical tips to help you get every drop of performance out of EE Shares ExpressionEngine is widely considered to be one of the most designer-friendly content management systems in use today.
Entire sites can be built using a simple template and group model, or it can be used to display highly dynamic content based on one or more templates: Having just recently completed and stabilised a tricky update to version 2. Many web designers praise the ease of use of the system, and thanks to some excellent documentation, those with limited technical knowledge can deploy sites on ExpressionEngine with relative ease.
Although ExpressionEngine runs very well straight out of the box, you may not be familiar with how to streamline your ExpressionEngine installation, and get every drop of performance out of it. I want to share some practical tips that you can perform on all of your ExpressionEngine sites. This article refers to the latest stable release of ExpressionEngine at the time of writing: Uninstalling modules ExpressionEngine uses a module system that allows it to dynamically load resources at runtime.
Features of EE such as RSS, Comments and Channel are modules that must be loaded by the system and initialised by the system before a page can be rendered. If you're not too familiar with ExpressionEngine, or if you're building your first ExpressionEngine site, you might not be familiar with what modules you need in order to complete your site. Below is a list of some commonly used modules and scenarios whereby it may be best to remove them.
These are not intended to be taken as gospel since each website will have its own unique requirements. If in doubt, leave the module installed. Designed to block IP addresses based on content submitted by visitors. If your site does not have a blog or news type channel that accepts comments or any form of input from visitors. Channel Installed by default. The most widely used module.
Allows you to display dynamic content in your templates. Although rare, if you're running an entirely static site based on templates and groups. This does somewhat defeat the purpose of using EE in the first place, but EE will run perfectly fine without it. Email Installed by default. Used when implementing contact forms and tell-a-friend functionality. If your site does not use contact forms or if you're using more powerful third party tools such as Solspace FreeForm Free.
Emoticon Installed by default. Intercepts user input in comments and replaces character combinations with their respective symbols. Member Installed by default. Allows you to accept member registrations through your website.
If your site does not accept or use membership registrations. This tag is prone to abuse by EE novices and is many times left switched on after development. Referrer Allows you to track website link referrals to your site. This module is fairly limited in scope, so a dedicated analytics package will provide more a in-depth analysis of link referrals. RSS Installed by default. Produces correct content headers for syndicated content such as RSS and Atom feeds. If your site does not provide RSS feeds or any other type of syndicated content.
SafeCracker Installed by default. This does not include comments on entries, which is powered by the Comment module. Search Installed by default. Allows you to create a search mechanism for visitors to search channel content. If your site does not have a search feature, or if you are using a third party system such as Google or Bing site search.
Statistics Installed by default. Lets you display site statistics in your templates such as total members logged in, total entries, last comment date etc.
If you are not displaying site statistics in your templates. This feature is heavily geared towards use on forums. Disable tracking ExpressionEngine has a little used tracking feature that is enabled by default. It is designed to track the number of times a template is viewed, along with channel entry views and site referrals.
Since this tracking feature is based solely on the number of times an item is viewed, you will find that the numbers produced are of little use. Statistics provided by dedicated analytics packages where visits can be filtered by new and recurring as well as cross referenced with site referrals and organic search results will typically be much more useful than the tracking provided by EE. Hence, if you are using an analytics system such as Google Analytics, it's best to disable the EE tracking features.
Delivering content faster Now we've got ExpressionEngine itself running as fast as possible, we can turn our attention to delivering our web pages as fast as possible. But first a note about serving static assets with EE. When a browser visits this site, ExpressionEngine will initialise, connect to the database, load necessary modules, parse the URL requested and then serve up the correct template.
Since most web servers treat each request as a separate thread, ExpressionEngine will need to initialise and perform the same steps again in order to serve the requested CSS template. Using this technique, ExpressionEngine runs twice for every web page requested and this is assuming you have only used a single CSS file. Template caching Template caching in EE is one of the easiest ways to boost site performance.
EE will effectively take the final HTML output for a page and store it as a static file ready for the next request for that page. This form of static caching is the fastest form of caching available and is as close as you can get to serving flat HTML files. Nonetheless there are tradeoffs to using template caching in EE. Beware of following scenarios where your site will not function correctly if you switch caching on: Member information and conditionals: If your templates display member information or use conditionals based on information about the currently logged in member.
If you have conditional code in your templates based on trying to ascertain the browser or visitor type for example, mobile and tablets. You'll need to keep the template caching Refresh Interval low in order to let the data displayed update regularly. If you are not using any of the scenarios mentioned above, or you're aware of the potential problems, template caching can be switched on a template by template basis.
To enable template caching: The refresh interval will be the number of minutes between the cache being refreshed. Gzip Compression This feature is very powerful when combined with template caching above. Gzip compression is the process of taking your HTML page and compressing so that it there is less data to transmit between the server and the browser. When the browser receives the data, it uncompresses it and displays that page as normal. Some older browsers don't support this feature, but thankfully ExpressionEngine is clever enough to detect them and transmit uncompressed data.
As with most things these days, your server needs to support gzip compression and if it does it will increase the server load slightly since the server will need to compress each page it transmits. This is why offsetting the slight server load increase with a decrease due to template caching is an excellent combination. To enable Gzip compression: Template optimisation, disabling PHP All the opimisation in the world is useless if you have hugely complex templates or processing intensive PHP code residing within them.
Your first steps should always be to optimise your templates by simplifying conditionals where possible or breaking parts of the page out into embedded templates. Removing all PHP from your templates, will also improve template parsing performance. Most, if not all, template PHP code can usually be moved to a plug-in for better performance and to help keep your templates easier to read. If you're not familiar with ExpressionEngine's plug-in architecture, there is a tutorial on the ExpressionEngine site: Browser optimisation Although not strictly an ExpressionEngine only optimisation, this technique is often forgotten by many web developers.
Most site optimisations focus on minimising the amount of time a visitor has to wait between the browser request and server response. Using effective server content-expires headers we can prevent the browser needing to make the browser request in the first place.
Content-expires headers are small bits of information that instruct the browser to hold on to a cached copy of the requested file for a certain amount of time. If we correctly configure content-expires headers for items such as images, then the browser will retrieve them from the cache instead of the web server. This effectively minimises the loading time for these assets to zero as a user navigates around your site.
If we were to update the CSS file, and someone were to visit the site with a cached copy of the CSS file, then their browser would not request the newly updated CSS file. They would be completely unaware that they are browsing the site with outdated style information, and might think that your site is broken. It's for this reason that we recommend only setting content-expires headers once the site is live and development is at a minimum.
Even so, there are many legitimate times when you need to update files when a site is in production. There are several solutions to this problem, but most of them revolve around the idea of cache-busting. Cache-busting is the technique whereby you append a query string to any links you want to control, and simply update this query string whenever you want a browser to update its cache.
Links with query strings still request the same file in this case the styles. The query string used in this case is irrelevant, but when a browser requests this CSS file it will be stored in its cache according to its full URL, which includes the query string. If we update the query string, the browser will think that the linked file is an entirely new file, and subsequently request it from the server, donwload it and cache it again.
So using this technique we can easily force browsers to refresh their caches by simply updating the query string.