In the second part of this series I described how to unlock a base level of performance out of your Joomla site with a few, simple changes. Today we're diving deeper into static media: JavaScript, CSS and image files. These changes are more involved but can turn a junker of a slow site into a decently performing one. Arguably, not all of these changes make sense for all sites but the performance benefits you get are substantial.

A large part of your site comes in the form of static media files: CSS, JavaScript, images and possible audio and video as well. We tend not to think much about them, considering them secondary to our content, but they typically make up the majority of the data transferred from our site's server to the user's device when they are visiting a page. Further to that, parsing large CSS and JavaScript files or decoding large images freezes up the main browser thread which, in simple terms, means that the browser cannot do any work for rendering the page (it can only download more data in the background). Moreover, the more CSS, JavaScript and image files you have the longer it takes for them to all be loaded which means that the browser has to stop rendering the page and recalculate everything from scratch every time one of these files finishes loading up. This can make the page appear slower or cause other rendering artefacts such as content jumping around the screen (that's called "Layout Shift" in the browser jargon).

Optimize your images

If you have a content-heavy site like this blog the biggest part of your page content transfer is the images. You are probably used to just taking an image, maybe resize or crop it a bit, upload it with Joomla's Media Manager or JCE's Media Manager and call it a day. Good for you, but your images are very likely unoptimized and larger (in Kilobytes, not necessarily dimensions) than they should be.

Maybe you are vaguely or keenly aware of tools such as pngcrush and mozjpeg. If you are comfortable with the command line do use them to optimize your images.

Even easier, there's a free tool called ImageOptim for macOS which can run several of these tools against your images and choose the smallest file. It's dead simple. Drag and drop your image folder onto the tool. Wait until it's done. Your images are replaced with their optimized versions. Obviously this should first be done on a local copy of your site. You could use Akeeba Backup to create a backup of your site and restore it locally to work on your site.

Please don't ask me about alternatives for Windows and Linux. I have not had the need for any, I haven't looked for any, I haven't used any.

Make your images adaptive

You already know that your site will be displayed in devices with different screen sizes: sub-5" bargain bin budget Android phones, 6" mainstream smartphones, 7"+ phablets or small tablets, 10"-11" tablets, 13"-15" laptops and massive 23"+ desktop monitors. You have already taken that into account by making your site responsive which means that your content scales and your design contorts itself to the interaction modes that are most appropriate for the screen size your site is rendering in.

But what about your images?

When your target devices range from a 380px wide budget phone to a 5120px wide desktop the same image file is not appropriate for all sizes. If you optimize for the small screen the image will look blurry and pixelated on the big screen. If you optimize for the big screen then most of your visitors are downloading an unnecessarily big file to display a much smaller image. Optimizing for the most common device size in your audience is the worst of both worlds: small devices download a big file and big screens show a blurry photo. If you also start taking into account HiDPI devices with pixel densities that are 2x, 3x or 4x the standard screen density (the standard is, by the way, 96 pixels per inch) you have quite the puzzle to solve. Do you go for a reasonably small file which will display badly on a lot of devices or a massive file which does display great in all devices but is in the ballpark of a couple Megabytes big?

Luckily, you do NOT have to choose. Browsers have long supported adaptive images. In short, using the PICTURE element with the appropriate media queries you can select the right image file for the screen your site is being rendered on. If the display size changes, e.g. the user rotated their device from portrait to landscape or resized their browser window on the desktop, the browser will smartly figure out what to do. If it has a large enough image it will scale it down. If it doesn't and you have hinted in your PICTURE element that a bigger image is available it will load the bigger image. While the bigger image is being loaded the smaller will appear scaled so from your user's perspective there's a bit of blur in the images that quickly goes away.

Another magic thing you can do with the PICTURE element is have the browser select the most appropriate file format it supports. Most images on the web are JPG or PNG. These are legacy image formats, dating back to the 1990s or even earlier. Most modern browsers also support WEBP, a much more efficient image file format which results in much smaller files while supporting transparency. From your perspective as a site builder it's like PNG on steroids. Unfortunately, you can't just go ahead and convert everything to WEBP because older browser versions (and all versions of Safari, as of this writing) do not support WEBP at all.

By now you might be clutching your head in despair. What was simply uploading a single image file and putting an IMG tag in your content has now become a puzzle which require you to create various different image sizes and image types. This is difficult for you, the site integrator, and outright impossible for your clients.

Luckily, there are third party Joomla extensions which can handle that for you. I have used XT Adaptive Images Pro. This site does not use this extension. Instead, I wrote a small library and a special layout override to automatically convert images as they are needed on my site. However, I am not your typical site integrator, I am primarily a backend developer. I found it easier to write customised PHP code for my site than use a third party solution. For everyone who's not me I strongly recommend using a third party extension to implement adaptive images.

Another point to be made about images is that illustrations (as opposed to photographs) typically start their life as a vector file in something like Adobe Illustrator or Affinity Designer. What we usually see is that these are converted to transparent PNG files before being used on a site. This is the least efficient way to go about it. Browsers have long supported scalable vector graphics (SVG) files, small text files which describe vector graphics. They tend to be much smaller than file formats optimized for photography (JPG, PNG and even WEBP), they are far more compressible due to them being plain text and can be scaled to any size from tiny to humongous on any screen resolution without losing crispness. The problem is that Joomla 3, by default, won't support SVG files for political reasons masqueraded as security concerns(*). If you want to use the far more efficient SVG files for your illustrations you can install my Joomla SVG Support plugin. I also recommend using JCE Pro and its media field override to make it easier to select SVG and other media files in third party components. One final note of caution: do not try to use SVG files in elements which expect to get their size from the content (SVG files do not have an intrinsic fixed width and height for all the browser cares) and don't try to use SVG files as background images. There are ways to do both but chances are you'll suffer unnecessarily.

* The "security concern" part has to do with the fact that SVG files can contain JavaScript. The concern was obliterated with Joomla's recommendation about adding .htaccess code which prevents JavaScript content in SVG files being executed when the file is accessed directly or placed on the page with an EMBED or OBJECT tag. SVG files placed on a page with an IMG tag never have their JavaScript executed in any browser version released this side of 2013 as a security precaution employed by the browsers themselves. Joomla 3 will still not add support for SVGs, even though it's changing 5 lines of code, because it's considered a "major feature" when it's really not and Joomla 4 accidentally applied the code changes required anyway, without anyone noticing, when the Media Manager component was rewritten. Oops :) Therefore the only reasons for which Joomla 3 still doesn't support SVG files out of the box are political, not security oriented.

Combine JavaScript and CSS

Remember when I alluded to the fact that having a lot of JavaScript and CSS files is slow? Let's dissect this a little bit. Back in 2010 it used to be the case that for every file you needed from the server your browser had to open a new HTTP(S) connection to the server, which carries a time penalty that's exacerbated on connections with long roundtrip (ping) times such as slow cellular networks, and wait for the file to be delivered. Also, browsers could only download up to 4 files from the server at a time. In 2020 browsers can download up to 8 files in parallel from a server and they keep the connection to the server open (no need to re-establish it) until they are finished rendering the page. Still, for each and every file you need to fetch from the server the browser needs to send a request and wait for a reply. This means that the roundtrip time is still important, i.e. slow mobile connections with a very high roundtrip time or accessing a far-away server suffers delays proportional to the number of JavaScript and CSS files being downloads.

Moreover, the browser doesn't magically know which files to download, HTTP/2 Push magically pushing some of these files with the main HTML content notwithstanding. It needs to parse the HTML page and start downloading files as it realizes they are required. This means that the JS and CSS files will be fully loaded by the browser at different points in time. Meanwhile, the browser can't just sit there twiddling its thumbs. It starts figuring out how to render the page and starts putting stuff on the screen. When a new CSS or JS files comes it stops what it's doing, parses the file and starts all over. The more files you have the more it has to stop and restart what it's doing. This means that your site's pages are slower to display in full, they "flash" a lot as content has to change positions on the screen and are harder on mobile devices' battery because the browser needs to expend much more effort to render your page. In short, the user experience SUCKS.

This is an easy problem to solve when you are in full control of the entire web application that generates your site: you know which bits of CSS and JS are used on each section of your site and combine them in one minified and compressed file before deploying the application. It also means that you have a large IT sub-department dealing with just the site and spend thousands to millions of dollars to maintain your site. On the other end of the spectrum we have sites based on off-the-shelf CMS like WordPress and Joomla which are an integration of a platform with various third party software. In our case that would be Joomla (the core CMS libraries) and all of its first- and third-party extensions. Each extension has its own CSS and JS files. Extensions don't know about each other and there's no support in Joomla itself for combining their CSS and JS files. It's easier and cheaper to build a site this way but performance sucks, as explained above.

You can use third party extensions, like my Combinator plugin, to force Joomla to combine individual CSS and JS files into a single file. I am using this plugin on this blog. It is a lot of work with a lot of trial and error to get everything just right but it pays dividends if your site is primarily accessed by mobile devices on cellular connections like this blog here.

Using a CDN

All of the above are great to know and even bother implementing at least once so you can fully appreciate the impact they have on the site's performance. There's something to be said, however, about the viability of maintaining these harder to employ site optimizations on dozens or hundreds of sites, i.e. the active maintenance site fleet of a typical web agency. At this point you may consider paying for CloudFlare instead.

CloudFlare is a combined CDN, site optimization and site security service. As a CDN it has nodes all over the world which will deliver your static files and cached pages lightning fast to your site's visitors. The optimization features it offers can automatically handle compression of your static resources and even combining JS and CSS (Rocket Loader). There's a small cost attached so it's not something I recommend for every site. For example, I am using CloudFlare on our business site but not this blog.

To be continued

Come back tomorrow for Part IV: Site building calisthenics.

3 thoughts on “Joomla Performance Tuning III: Static Media Optimization”

  1. Tuesday, 11 May 2021 23:27

    Great articles,

    Thank fully I have evolved a similar approach to Joomla set up. I learned Joomla through creating PHP templates back in 2008 but now use Gantry because I love the Particles and my javascript is not yet good enough to replace them.

    Your .htaccess tips and snippets are great, really useful. 

    You mention Cloudflare here.

    Any tips on setting up these two areas for Joomla 3?

    https://imgur.com/a/0Y1tnGw

    1. Wednesday, 12 May 2021 09:04

      What you have is right. Just remember to create a Page Rule to disable caching for the /administrator/* URLs so that CloudFlare does not get in the way of your backend administration.

      1. Wednesday, 12 May 2021 23:49

        I had done that in fact but good point for other readers too.

        The .htaccess snippets and http/2 plugin allowed me to turn of JCH Optimize on two ecommerce sites. JCH was a plugin I had sworn by for years. For the most part it served a purpose. However, some of your advice, and some brushing up on javascript finally convinced me to let it go.

        The two sites now run slightly faster, and 'better'

        So, well worth the read.

        I look forward to reading more. Refreshing to see some qualified information in ne place rather than piece together oddments from Google searches.