Leverage Joomla browser caching

Leverage Joomla browser caching

Are you wondering how to make your Joomla website faster? Well, there are many possibilities, but we would like now to introduce the one that does not require much effort. Leverage Joomla browser caching is often recommended by Google.

This method involves the re-use of files already existing at the user and not requiring a download again.

It does not require many changes, and it’s easy to make. Extending the cache lifetime results in the user saving the time usually required to download the same files each time they visit the site.

Increase browser cache by changing the .htaccess file

The whole process requires a modification in the .htaccess files which you can find in the root of your web site's hosting server. The file edition will allow setting the expiry time of images and CSS files by changing the expire headers.

How to do it? You need to access your hosting CPanel and using any text editor find the .htaccess file (it’s hidden - use the FTP tool like FileZilla), then add the following content (set caching parameters) at the bottom of the file. That’s all. You can save the file (not as a .txt file).
  1. # ----------------------------------------------------------------------
  2. # CORS-enabled images (@crossorigin)
  3. # ----------------------------------------------------------------------
  4. # Send CORS headers if browsers request them; enabled by default for images.
  5. # developer.mozilla.org/en/CORS_Enabled_Image
  6. # blog.chromium.org/2011/07/using-cross-domain-images-in-webgl-and.html
  7. # hacks.mozilla.org/2011/11/using-cors-to-load-webgl-textures-from-cross-domain-images/
  8. # wiki.mozilla.org/Security/Reviews/crossoriginAttribute

  9. <IfModule mod_setenvif.c>
  10. <IfModule mod_headers.c>
  11. # mod_headers, y u no match by Content-Type?!
  12. <FilesMatch "\.(gif|png|jpe?g|svg|svgz|ico|webp)$">
  13. SetEnvIf Origin ":" IS_CORS
  14. Header set Access-Control-Allow-Origin "*" env=IS_CORS
  15. </FilesMatch>
  16. </IfModule>
  17. </IfModule>

  18. # ----------------------------------------------------------------------
  19. # Webfont access
  20. # ----------------------------------------------------------------------
  21. # Allow access from all domains for webfonts.
  22. # Alternatively you could only whitelist your
  23. # subdomains like "subdomain.example.com".

  24. <IfModule mod_headers.c>
  25. <FilesMatch "\.(ttf|ttc|otf|eot|woff|woff2|font.css|css|js)$">
  26. Header set Access-Control-Allow-Origin "*"
  27. </FilesMatch>
  28. </IfModule>

  29. <IfModule mod_deflate.c>
  30. <FilesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|js|css|swf)(\.gz)?$">
  31. SetOutputFilter DEFLATE
  32. # Header set Expires "max-age=29030400, public"
  33. Header unset ETag
  34. FileETag None
  35. </FilesMatch>
  36. </IfModule>

  37. #
  38. # Sources:
  39. # http://stackoverflow.com/questions/7704624/how-can-i-use-gzip-compression-for-css-and-js-files-on-my-websites
  40. # http://codex.wordpress.org/Output_Compression
  41. # http://www.perun.net/2009/06/06/wordpress-websites-beschleuinigen-4-ein-zwischenergebnis/#comment-61086
  42. # http://www.smashingmagazine.com/smashing-book-1/performance-optimization-for-websites-part-2-of-2/
  43. # http://gtmetrix.com/configure-entity-tags-etags.html
  44. # http://de.slideshare.net/walterebert/die-htaccessrichtignutzenwchh2014
  45. # http://de.slideshare.net/walterebert/mehr-performance-fr-wordpress
  46. #

  47. <IfModule mod_deflate.c>
  48. # Insert filters / compress text, html, javascript, css, xml:
  49. AddOutputFilterByType DEFLATE text/plain
  50. AddOutputFilterByType DEFLATE text/html
  51. AddOutputFilterByType DEFLATE text/xml
  52. AddOutputFilterByType DEFLATE text/css
  53. AddOutputFilterByType DEFLATE text/vtt
  54. AddOutputFilterByType DEFLATE text/x-component
  55. AddOutputFilterByType DEFLATE application/xml
  56. AddOutputFilterByType DEFLATE application/xhtml+xml
  57. AddOutputFilterByType DEFLATE application/rss+xml
  58. AddOutputFilterByType DEFLATE application/js
  59. AddOutputFilterByType DEFLATE application/javascript
  60. AddOutputFilterByType DEFLATE application/x-javascript
  61. AddOutputFilterByType DEFLATE application/x-httpd-php
  62. AddOutputFilterByType DEFLATE application/x-httpd-fastphp
  63. AddOutputFilterByType DEFLATE application/atom+xml
  64. AddOutputFilterByType DEFLATE application/json
  65. AddOutputFilterByType DEFLATE application/ld+json
  66. AddOutputFilterByType DEFLATE application/vnd.ms-fontobject
  67. AddOutputFilterByType DEFLATE application/x-font-ttf
  68. AddOutputFilterByType DEFLATE application/x-web-app-manifest+json
  69. AddOutputFilterByType DEFLATE font/opentype
  70. AddOutputFilterByType DEFLATE image/svg+xml
  71. AddOutputFilterByType DEFLATE image/x-icon
  72. # Exception: Images
  73. SetEnvIfNoCase REQUEST_URI \.(?:gif|jpg|jpeg|png)$ no-gzip dont-vary
  74. # Drop problematic browsers
  75. BrowserMatch ^Mozilla/4 gzip-only-text/html
  76. BrowserMatch ^Mozilla/4\.0[678] no-gzip
  77. BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html
  78. # Make sure proxies don't deliver the wrong content
  79. Header append Vary User-Agent env=!dont-vary
  80. </IfModule>

  82. <IfModule mod_expires.c>
  83. ExpiresActive On
  84. ExpiresDefault "access plus 1 week"
  85. ExpiresByType image/jpg "access plus 1 year"
  86. ExpiresByType image/jpeg "access plus 1 year"
  87. ExpiresByType image/gif "access plus 1 year"
  88. ExpiresByType image/png "access plus 1 year"
  89. ExpiresByType image/svg+xml "access plus 1 month"
  90. ExpiresByType text/css "access plus 1 month"
  91. ExpiresByType text/html "access plus 1 minute"
  92. ExpiresByType text/plain "access plus 1 month"
  93. ExpiresByType text/x-component "access plus 1 month"
  94. ExpiresByType text/javascript "access plus 1 month"
  95. ExpiresByType text/x-javascript "access plus 1 month"
  96. ExpiresByType application/pdf "access plus 1 month"
  97. ExpiresByType application/javascript "access plus 1 months"
  98. ExpiresByType application/x-javascript "access plus 1 months"
  99. ExpiresByType application/x-shockwave-flash "access plus 1 month"
  100. ExpiresByType image/x-icon "access plus 1 year"
  101. ExpiresByType application/json "access plus 0 seconds"
  102. ExpiresByType application/ld+json "access plus 0 seconds"
  103. ExpiresByType application/xml "access plus 0 seconds"
  104. ExpiresByType text/xml "access plus 0 seconds"
  105. ExpiresByType application/x-web-app-manifest+json "access plus 0 seconds"
  106. ExpiresByType text/cache-manifest "access plus 0 seconds"
  107. ExpiresByType audio/ogg "access plus 1 month"
  108. ExpiresByType video/mp4 "access plus 1 month"
  109. ExpiresByType video/ogg "access plus 1 month"
  110. ExpiresByType video/webm "access plus 1 month"
  111. ExpiresByType application/atom+xml "access plus 1 hour"
  112. ExpiresByType application/rss+xml "access plus 1 hour"
  113. ExpiresByType application/font-woff "access plus 1 month"
  114. ExpiresByType application/vnd.ms-fontobject "access plus 1 month"
  115. ExpiresByType application/x-font-ttf "access plus 1 month"
  116. ExpiresByType font/opentype "access plus 1 month"
  117. </IfModule>
  118. ## EXPIRES CACHING ##

  119. #Alternative caching using Apache's "mod_headers", if it's installed.
  120. #Caching of common files - ENABLED
  121. <IfModule mod_headers.c>
  122. <FilesMatch "\.(ico|pdf|flv|swf|js|css|gif|png|jpg|jpeg|txt|html|htm)$">
  123. Header set Cache-Control "max-age=2592000, public"
  124. </FilesMatch>
  125. </IfModule>

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

  131. <IfModule mod_gzip.c>
  132. mod_gzip_on Yes
  133. mod_gzip_dechunk Yes
  134. mod_gzip_item_include file \.(html?|txt|css|js|php|pl)$
  135. mod_gzip_item_include handler ^cgi-script$
  136. mod_gzip_item_include mime ^text/.*
  137. mod_gzip_item_include mime ^application/x-javascript.*
  138. mod_gzip_item_exclude mime ^image/.*
  139. mod_gzip_item_exclude rspheader ^Content-Encoding:.*gzip.*
  140. </IfModule>

  141. # Set Keep Alive Header
  142. # This *just* sets the header - maybe your hoster is not allowing this feature
  143. # Please check if it is working with tools like http://www.webpagetest.org
  144. <IfModule mod_headers.c>
  145. Header set Connection keep-alive
  146. </IfModule>

  147. # If your server don't support ETags deactivate with "None" (and remove header)
  148. <IfModule mod_expires.c> 
  149. <IfModule mod_headers.c>
  150. Header unset ETag
  151. </IfModule>
  152. FileETag None
  153. </IfModule>
Expires headers inform the browser whether they should request a specific file from the server or grab it directly from the browser's cache.

So in practice, they do not improve page speed for a first-time visit as this visitor would have to download all the files. But they significantly decrease load times for returning visitors. Expires headers can be set on specific file types.

You can set different expiry times. For these files that are often updated, it would be good to set earlier expiry date.

A tip - Set expiry at a minimum of one month and no more than a year ( it depends on you). Files should refresh as quickly as the HTML of the website.

Set short expiry times for things that change regularly. If your website visitor comes again within a month, he does not have to need to download your CSS and JS files again. Files that take the most time to download are kept on the visitor's machine.

Remember that enabling browser caching and setting up the parameters for too long might affect on the lack of a fresh version of your website after any updates.

If entering the code itself does not give results, it is worth to perform additional activities such as "enable optimization in the template parameters.

Learn more about ways to speed up, optimize your website.

    Please note that a new version of the knowledge base is available at 

      • Related Articles

      • DJ-MegaMenu Joomla 4 Module options

        DJ-MegaMenu module is necessary to display the menu in the module position.  Navigate Content > Sitem modules and choose the DJ-MegaMenu module. Let's take a look at Module Parameters: Menu Name – The name of the menu (default is main menu) Base ...
      • How to install the DJ-Classifieds Joomla 4.x quickstart?

        What is Quickstart? The Quickstart is the backup (zipped copy) of the Joomla 4.x demo from our demo site. After the successful installation, you get the same effect as on our demo pages. You do not need to configure everything from scratch; the ...
      • How to add images using the file browser

        Adding images from the server is now possible with the new file browser. The DJ-MediaTools 2.13 version introduces this feature. Let's see how to use it. Open the DJ-MediaTools component. Go to " New item ." You should fill in all the data for your ...
      • DJ-Accessibility Joomla installation

        Download and install the DJ-Accessibility plugin from the download section. You install the package as any other Joomla extension. 
      • Migrate from Joomla 1.5

        If you're currently using the version for Joomla 1.5, we have prepared the migration package that will help you migrate DJ-Classifieds to Joomla 2.5. Below you can find step by step instructions on how to proceed. Please notice that migration can not ...