Configuring Server Side Page Caching in Joomla
Server side page caching is an important part of reducing the render time for your web site and thus improving your user experience. The load time is also used by Google and other search engines to assist in ranking pages--faster page loads will result in better rankings. Joshua Bixby provides and excellent discussion of how load times are calculated by search engines in 13 Questions (and Answers) About Google, Site Speed and SEO. The article that follows describes how to use Joomla's built-in caching capabilities, how to use Akeeba Admin Tool’s .htaccess generator to improve performance, how to configure a popular caching extension to further improve web site performance, how to use various image optimization tools for lossless compression, and how you should set up JavaScript for asynchronous loading. The article discusses Google’s PageSpeed utility as a way to test the results of various configuration changes. The article is divided into the following sections:
- Google PageSpeed Webmaster Tool
- Native Joomla Caching and Compression
- Using Akeeba Admin Tools to Write .htaccess
- Using the JCHOptimize Extension to Compress, Minify, and Merge
- Using the JBetolo Extension to Compress, Minify, and Merge
- Image Compression with optipng
- Image Compression with jpegtran
- Client Side Caching
- Using Asynchronous Loading for JavaScript
- Testing
- Google Analytics Timing Results
Google PageSpeed Webmaster Tool
The article that follows is shows how to use Joomla settings and the JBetolo extension to improve page loading time and in particular, to improve the Google PageSpeed score for a page. PageSpeed is a utility for analyzing the way a page is optimized to reduce the time it takes to render the page in a browser. A good PageSpeed score is helpful in getting a good user experience in many cases. For a low volume web site where the server cache expires before every access, turning on the various settings for caching can actually slow down the render time as the server rebuilds the cache before serving the page. In this low volume case, getting a good PageSpeed score for your site will actually hurt your render times. You will have to experiment to determine what works best for rendering your web site.
The PageSpeed is located at https://developers.google.com/speed/pagespeed/insights/?hl=en&utm_source=wmx&utm_campaign=wmx_otherlinks
.
To use PageSpeed, just enter the URL of the page that you want to analyze. All of the examples in this article are from the page https://www.mooresoftwareservices.com/loan-pricing/9-effective-yield-loan-fee-amortization
on this site. The page contains basic HTML, tables, and calls to MathJax to render mathematical formulas, but it does not contain much in the way of images. Figure 1 shows the Google PageSpeed rating for this page with no compression or caching enabled.

The Google PageSpeed algorithm rewards a number of things, that generally fall in three categories for items that can be improved via Joomla and JBetolo configuration:
- Minify
- Compress
- Merge
These three categories will be described in the following sections.
Minify
Minifying a file is the process of removing unnecessary characters from the file, typically spaces, line end characters, comments and other characters that are not needed to for correct execution of the file. A minified file does not need to be “un-minified” by the client browser. Minifying generally does not break things on a Joomla web site, but it does take server processing.
Compression
Compression is the process of reducing the size of the file using a compression program. Unlike a minified file, a compressed file DOES need to be uncompressed prior to execution by the client browser. Compression generally does not break things on a Joomla web site, but it does take server processing.
Merging
Merging is the process of combining a number of CSS or JavaScript files into a single CSS file and a single JavaScript file. Because browsers generally only open two download channels to a host at a time, there is a lot of overhead in starting the download processing for a large number of CSS and JavaScript files. By merging files, you can speed up the download process by eliminating the overhead of starting all of the different streams. Merging files frequently DOES break things with other Joomla extensions. You will need to do a lot of testing before you turn merging on in production.
Native Joomla Caching and Compression
Joomla has a basic built-in compression and caching capability that is implemented by setting Joomla configuration variables in the configuration.php
file. Joomla does not have a native merging capability. The Joomla native caching has one major drawback--all article retrievals from cache will not be reflected in the hit counts for the articles. In the Global Configuration panel shown in Figure 2, setting the file type and cache time will set the cache variables as shown Figure 3:

public $caching = '0';
public $cache_handler = 'file';
public $cachetime = '10';
Similarly, the native setting for GZIP compression is on the system panel as shown in Figure 4.

For my web page, the native Joomla cache and compression settings didn't really improve the PageSpeed score and that much and broke the Joomla internal hit counters for articles so that I didn't have accurate information on which articles were getting traffic. At this point, I started looking for extensions that would handle the caching and which would maintain accurate hit counts for all of my articles.
Using Akeeba Admin Tools to Generate .htaccess
Akeeba Admin Tools have the capability to generate a .htaccess file that will do a great deal to secure your Joomla web site, but which will also set up the compression and most of what you need to get a good score on Google PageSpeed. In the section Custom .htaccess rules shown in Figure 5, add the local caching rules listed in Figure 15.

Using the JCH Optimize Extension to Compress, Minify, and Merge
To improve PageSpeed scores and speed up a site, there are a number of Joomla extensions that offer improved caching, minification, compression, in addition to consolidation of JavaScript and CSS files, plus lazy loading of images. After some trial and error, I ended up using the paid version of JCH Optimize for caching, minification, consolidation and lazy loading. With about four hours of testing, I was able to get all pages on my site to render properly; the problematic pages and the solutions are discussed in the sections that follow:
- Basic JCH Optimzie Configuration
- Getting in-Article Google Trends Scripts to Work Properly
- Getting MathJax Formulas to Render Properly
- Getting Google Analytics to Work Properly
- Getting Template Images to Work with Lazy Loading
- CSS Delivery
Basic JCH Optimzie Configuration
JCH Optimize has a great set of standard settings shown in Figure 6 that progressively turn on additional features that make it easy to test which settings break which pages. Most of the pages on this site worked with “Average” but with some additional testing, I was able to get more aggressive in the settings. The only thing basic setting that I have not been able to enable is the “Defer JavaScript” option shown in Figure 7. The next section describes the changes necessary to get the Google Trends displays working properly.


Getting in-Article Google Trends Scripts to Work Properly
A number of the articles on this site use Google Trends embedded JavaScript calls within an article; Traffic2cash.xyz Google Analytics Referral Spam is an example of an article that shows Google search trends. To get these to work, I had to disable the JavaScript consolidation option for scripts that occur between the <body> and </body> tags as shown in Figure 8. This option is only turned on in the higher levels of optimization in JCH Optimize.
The next section discusses the changes necessary to get MathJax working properly.

Getting MathJax Formulas to Render Properly
To use the advanced settings in JCH Optimize, you will almost certainly need to exclude some extensions or scripts from the consolidation and other advanced features; this is done in the “Exclude Options” tab in JCH Optimize. Many of the pages on this site use MathJax to render mathematical formulas; Effective Interest (Yield) Amortization of Loan Points to Income is an example of an article that uses MathJax to render formulas. MathJax requires calling a JavaScript program in the header to a site. I use the JaTex plugin to do this. To get these formulas to render properly, I had to exclude this extension from the JavaScript consolidation as shown in Figure 10.
The next section discusses how to use the advanced settings to get Google Analytics to work.


Getting Google Analytics to Work Properly
Many Joomla sites use Google Analytics for search engine optimization (SEO) analysis, and use the sh404SEF to manage the insertion of the code to call Google Analytics for visit logging. To get this to work, you will need to exclude this script as shown in Figure 11. To test this, you will need to go to the “Real Time” section in Google Analytics without any filters for your home location and then open a browser that does not disable tracking to force activity in Google Analytics. If everything is working properly, you will see your browsing activity in the Real-time section of Google Analytics.
The next section shows how to enable lazy loading for images.

Getting Template Images to Work with Lazy Loading
If you have articles with a large number of screen captures or other images (like this article), you may want to enable lazy loading of images to reduce server load and improve page load times. With lazy loading enabled, an image does not load until the reader scrolls down to that portion of the article. With lazy loading enabled, you may need to exclude some images that are displayed as part of the template, as shown in Figure 13.
The next section talks about optimizing CSS delivery to improve render time.

CSS Delivery
In Google PageSpeed, one of the metrics discusses reducing the amount of data that must be downloaded before the first screen can be rendered. Under the Pro Options in JCH Optimize, you can attempt to do this using the “Optimize CSS” delivery option. This option can take some significant trial-and-error testing and is probably the option most likely to break after system maintenance.

Using the JBetolo Extension to Compress, Minify, and Merge
This article was originally written to describe setting up server side caching with jBetolo, but I had repeated problems getting it to work propery with MathJax, the Joomla print/email icons (an icon font) and other things so I switched to the paid JCH Optimize plugin and have had a much easier time getting that plugin to work.
Image Compression with optipng
PageSpeed will point out any PNG images that need to be compressed. For PNG images, the optipng
command line utility available from http://optipng.sourceforge.net/ will compress images and make PageSpeed happy. On Ubuntu, you can install this with the command sudo apt-get install optipng
, while on windows you will have to download and install the binary from the SourceForge web site. Figure 14 shows how to call optipng
from the command line to compress all of the files in a directory.
optipng *.png
** Processing: joomla_admin_config_server_compression.png
979x881 pixels, 4x8 bits/pixel, RGB+alpha
Input IDAT size = 157917 bytes
Input file size = 158027 bytes
Trying:
zc = 9 zm = 8 zs = 0 f = 0 IDAT size = 157917
joomla_admin_config_server_compression.png is already optimized.
Image Compression with jpegtran
PageSpeed will point out any JPEG images that can be compressed. For JPEG images, the jpegtran
command line utility available from http://jpegclub.org/ will losslessly optimize the internal structures in JPEG images and reduce the size by 10-20% in many cases without loss of image quality. The command is not quite as simple as the optipng tool, as you will either need to write a script or run the command several times:
jpegtran -copy none -progressive -optimize input.jpg > output.jpg
Client Side Caching
The final step in setting up caching is to configure the client browser expiration settings for your web site. Google PageSpeed recommends setting the client side cache expiration to a minimum of one week (604,800 seconds), which works well for most content. The .htaccess
generator in Akeeba Admin tools will do this for you but if you are not using Akeeba Admin Tools, you will want a section in your .htaccess
that looks something like the example shown in Figure 15.
#
# Expiration
#
#
# Expiration
#
ExpiresActive On
ExpiresDefault "now plus 1 hour"
# CSS and JS expiration: 1 week after request
ExpiresByType text/css "now plus 1 week"
ExpiresByType application/JavaScript "now plus 1 week"
ExpiresByType application/x-JavaScript "now plus 1 week"
# Fonts
ExpiresbyType application/x-font-ttf "now plus 1 month"
ExpiresbyType application/octet-stream "now plus 1 month"
ExpiresbyType font/truetype "now plus 1 month"
ExpiresbyType font/ttf "now plus 1 month"
ExpiresbyType application/x-font-woff "now plus 1 month"
ExpiresbyType application/font-wof "now plus 1 month"
ExpiresbyType application/x-woff "now plus 1 month"
ExpiresbyType application/vnd.ms-fontobject "now plus 1 month"
# Image files expiration: 1 month after request
ExpiresByType image/bmp "now plus 1 month"
ExpiresByType image/gif "now plus 1 month"
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 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"
# Audio files expiration: 1 month after request
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/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"
The font moonico.woff
requires the application/x-font-woff
two entries in the expiration list, and may require others. This font is used for the print, email, edit and search icons and is the most difficult thing to get working reliably with Jbetolo. Without these entries, you will have a page that looks fine until it expires.
Using Asynchronous Loading for JavaScript
The page that I used for testing in this example calls MathJax to render some mathematical formulas. MathJax is implemented in JavaScript and is called via
<script type="text/JavaScript" src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
</script>
If you are not using a plugin to add the MathJax code, you can converting this synchronous script loading to asynchronous loading by adding async
to the call got rid of the red “You Should Fix” section of recommendations in the PageSpeed list for this page and improved the PageSpeed score by one point. The asynchronous syntax is shown below:
<script async type="text/JavaScript" src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
</script>
Testing
It is important to test using all major browsers, as optimizations that work in Firefox and Safari may not work in Chrome and Internet Explorer, both of which are more common. If figuring out what is going on and what is blocking rendering, the Firefox developer tools can be quite useful. Figure 11 shows the a native compression only retrieval of the page while Figure 11 shows a retrieval with merging turned on for both CSS and JavaScript. Note that the JBetolo time is about 10% shorter than the native time (1.88 vs. 2.08), and that the time to render the first display is shorter still, though the latter isn't easy to tell from the displays. Make sure to do several retrievals, as they will vary dramatically from retrieval to retrieval depending upon server and network load, the 1.88 and 2.08 are not statistically valid numbers in any way. The most obvious difference is that the number of bytes required has been cut by more than 50%, from 744K to 354K. The results reported by Google Analytics are probably the best measure of how well your optimizations are working.


Google Analytics Timing Results
For a 30 day period where the no caching was enabled but compression was enabled (PageSpeed score of 67 for example page), Google Analytics reported an average load time of 5.12 seconds. Average load times with merging, minification and compression turned on in JCH Optimize will be added at a future date, but appear to be under 2 seconds.