In the first part of this series I described why tuning the performance of your site is something you should do for both philosophical and practical reasons, as well as where to start. That post was by necessity a bit generic. In the second part of this series we'll dive into some of the basic things you can do in Joomla to unlock a decent amount of performance.
Basic system settings
When building a site we get so caught up in the design and functionality that we forget that some very basic and fairly straightforward system settings can have a massive impact on the performance of our sites. A few simple switches in the Global Configuration before delivering the site and a few simple server checks can make all the difference in the world.
Most of the time spent on the server side of a site has to do with constructing the page that will be displayed to the visitor. Joomla, unlike WordPress, has a built-in caching system. I feel that people don't give it enough credit because they were used to the subpar caching experience in Joomla 1.0 to 2.5. That was 10 to 15 years ago.
Go to your site's Global Configuration and set caching to "ON - Progressive Caching". The progressive caching option is the better form of Joomla built-in caching, making sure that all elements of your page are cached. When a request comes through, the page is stitched together from cached content whenever possible. This can even work towards mitigating some of the performance lost to a pre-built template. It will definitely work towards making your public, non-logged-in pages faster – exactly what is most relevant for your site's search engine ranking.
As to the caching back-end, I've found that file caching on a decent host is similar or better in performance than memcached or Redis. Heresy, I hear you say. And I agree, to an extent. If you have a truly massive or extremely busy site it makes sense to use a dedicated memcached or Redis server. It will be faster. Chances are that if you're reading this you do not, in fact, have this kind of site and you're looking at speeding up a much more pedestrian site. Even my business site falls into the "more pedestrian" category and we're getting a healthy number of dozens of thousands of unique monthly visitors. That should give you a sense of the site scale that would benefit from non-file caching.
If there was a contest for the most-overlooked option in Joomla, Gzip Page Compression would win hands down. If you haven't already done so, go ahead and enable it.
This option makes sure that the HTML content sent by your site to the browser is compressed using the GZip (also called "deflate") algorithm. This reduces the total size of the data transferred to the client substantially. The amount of time saved in data transfer has a significant impact to your site's performance.
I strongly recommend doing this through your web server itself. If you are using Apache you can add the following to your .htaccess file:
mod_gzip_item_include file \.(html?|txt|css|js|php|pl|xml|rb|py|svg|scgz)$
mod_gzip_item_include mime ^text/plain$
mod_gzip_item_include mime ^text/xml$
mod_gzip_item_include mime ^text/css$
mod_gzip_item_include mime ^application/xml$
mod_gzip_item_include mime ^application/xhtml+xml$
mod_gzip_item_include mime ^application/rss+xml$
mod_gzip_item_include mime ^image/svg+xml$
mod_gzip_item_exclude rspheader ^Content-Encoding:.*gzip.*
mod_gzip_item_include handler ^cgi-script$
mod_gzip_item_include handler ^server-status$
mod_gzip_item_include handler ^server-info$
mod_gzip_item_include handler ^application/x-httpd-php
mod_gzip_item_exclude mime ^image/.*
Your web server is much faster in compressing static media files and it can keep the compressed files cached in memory for speedier delivery next time around.
Static media caching
Reducing the size of the static media with compression is half the battle and matters primarily for first time visitors. When someone comes back to your site it makes sense for their browser to serve static media from the browser's cache, without hitting the network at all. If you're using Apache you can use the following code in your .htaccess file:
# Enable expiration control
# CSS and JS expiration:
ExpiresByType text/css "now plus 1 year"
# Image files expiration: 1 month after request
ExpiresByType image/bmp "now plus 1 year"
ExpiresByType image/gif "now plus 1 year"
ExpiresByType image/jpeg "now plus 1 month"
ExpiresByType image/jp2 "now plus 1 month"
ExpiresByType image/pipeg "now plus 1 month"
ExpiresByType image/png "now plus 1 month"
ExpiresByType image/svg+xml "now plus 1 month"
ExpiresByType image/tiff "now plus 1 month"
ExpiresByType image/vnd.microsoft.icon "now plus 1 month"
ExpiresByType image/x-icon "now plus 1 month"
ExpiresByType image/ico "now plus 1 month"
ExpiresByType image/icon "now plus 1 month"
ExpiresByType image/webp "now plus 1 month"
ExpiresByType text/ico "now plus 1 month"
ExpiresByType application/ico "now plus 1 month"
ExpiresByType image/vnd.wap.wbmp "now plus 1 month"
ExpiresByType application/vnd.wap.wbxml "now plus 1 month"
ExpiresByType application/smil "now plus 1 month"
# Font files expiration: 1 week after request
ExpiresByType application/vnd.ms-fontobject "now plus 1 week"
ExpiresByType application/x-font-ttf "now plus 1 week"
ExpiresByType application/x-font-opentype "now plus 1 week"
ExpiresByType application/x-font-woff "now plus 1 week"
ExpiresByType font/woff2 "now plus 1 week"
ExpiresByType image/svg+xml "now plus 1 week"
# Audio files expiration: 1 month after request
ExpiresByType audio/ogg "now plus 1 month"
ExpiresByType application/ogg "now plus 1 month"
ExpiresByType audio/basic "now plus 1 month"
ExpiresByType audio/mid "now plus 1 month"
ExpiresByType audio/midi "now plus 1 month"
ExpiresByType audio/mpeg "now plus 1 month"
ExpiresByType audio/mp3 "now plus 1 month"
ExpiresByType audio/x-aiff "now plus 1 month"
ExpiresByType audio/x-mpegurl "now plus 1 month"
ExpiresByType audio/x-pn-realaudio "now plus 1 month"
ExpiresByType audio/x-wav "now plus 1 month"
# Movie files expiration: 1 month after request
ExpiresByType application/x-shockwave-flash "now plus 1 month"
ExpiresByType x-world/x-vrml "now plus 1 month"
ExpiresByType video/x-msvideo "now plus 1 month"
ExpiresByType video/mpeg "now plus 1 month"
ExpiresByType video/mp4 "now plus 1 month"
ExpiresByType video/quicktime "now plus 1 month"
ExpiresByType video/x-la-asf "now plus 1 month"
ExpiresByType video/x-ms-asf "now plus 1 month"
HTTPS and HSTS
There's a common misconception that HTTPS has something to do with securing your site, it's expensive, it's slow and you don't really need it unless you're doing e-commerce or something. Another misconception is that it makes your site slower.
These myths originated in the late 1990s. Over two decades ago they are patently false.
HTTPS is pretty much mandatory these days. If you don't use HTTPS your site will appear with a red sign stating it's insecure, scaring visitors away. It will be penalized by search engines. You should use HTTPS if only to fix these two problems. You don't even need to break the piggy bank. TLS certificates are now free of charge thanks to Let's Encrypt. Most hosting control panels integrate with Let's Encrypt, meaning that you can literally have your hosting control panel issue and install a free TLS certificate and auto-renew it. There is zero maintenance on your part. HTTPS is also super fast since any modern CPU, released over the past ten-odd years, has hardware acceleration for the cryptographic operations it uses.
While you're at it, remember to set Force HTTPS to Entire Site in your Global Configuration. This ensures that your Joomla site will always be delivered over HTTPS, making logins more secure in the process. Once you do that and you've confirmed HTTPS works great with your site add the following to your .htaccess:
Header always set Strict-Transport-Security "max-age=31536000" env=HTTPS
This enables a feature called HSTS (HTTP Strict Transport Security). In short, it tells your browser to never even try to connect to the HTTP version of your site, regardless of what your visitor tells it to do. Since this happens on the browser side a visitor who types your domain name in the address bar without the https:// prefix, or clicks a link with the http:// prefix, will always get to the HTTPS version of your site without having to first visit the plain HTTP version and get redirected by Joomla. This is much faster, especially on high-latency connections such as mobile or satellite Internet.
A further optimization you can do is submit your site to the HSTS Preload List. While HSTS only works after the first time someone visits your site, having your site in the HSTS Preload List means that the browser knows about your site using HSTS before the first time your visitor visits it. Therefore, the browser will never attempt to load it over plain HTTP. Again, this is a time saver for high-latency connections, easy and free. What's not to love about it?
HTTP/2 Server Push
The ulterior motive for using HTTPS is that it enables us to use HTTP/2. This is a newer version of the HTTP protocol which only works over HTTPS, uses binary headers and supports a few important features that increase the performance of the site.
This is something your host needs to enable on their server. If you are not sure if they do, go to https://http2.pro/ and test the HTTPS version of your site. If it tells you that HTTP/2 is not supported please do contact your host and ask them to enable it.
While Joomla does not have built-in HTTP/2 Server Push support (yet?), you can always use Michael Richy's Server - HTTP/2 Push plugin. Do remember that HTTP/2 Push only happens the first time a visitor requests a resource during the user session. When you are testing it on your site do remember to not just clear your browser's cache but also the cookies sent by your site to reset the session.
To be continued
Come back tomorrow for Part III: Static media optimisation.