2

Ive just run a google page speed test on my site and one of the things its suggested to do is use browser caching. I already do you browser caching for most large images and other assets that in frequently change, but its also suggesting i add browser cacheing for :

  • UI .png images
  • Minified CSS
  • Minified JS
  • Google analytics JS tag from Google CDN (currently 2 hours cache)
  • 3rd party JS tracking tag from 3rd party CDN (currently 4 hours cache)

On the last 2 which are hosted by 3rd parties so i cant set the cache settings.

On the first 3 bullet points, i dont really want to set them to be cached as if for instance there was a change to the navigation of the website the HTML, CSS, JS, and UI graphics would all need to be updated, if a user had some of that cached, it could mean that they where served HTML which was not in sync with the cached JS, CSS, UI pngs.

Is there a way to get around this by be able to set something browser or server side that would allow me to cache the JS, CSS, UI pngs, but if / when i make a change and they need to be updated i could put up a notice that lets all visitors browsers know to re download all the assets and not use their previous cache ?

In case its asked : Server wise the site is running Apache.

5
  • You are looking for "cache busting": The practice of putting version numbers in your asset URLs. Commented Sep 5, 2017 at 10:54
  • Hi @StephenOstermiller i was thinking of putting version numbers in the assets URL / Names to overcome this, but it seems quite messy to manage as to update a file name i would also need to update various bits of code the reference the new file name. If i changed 10 files i might have to make 30+ code changes.
    – sam
    Commented Sep 5, 2017 at 11:05
  • Version number cache busting works best with non-static websites that are powered by templated pages from a framework or CMS. You would tyically call some code to write the URLs for the assets that would add the version numbers. That way there is a single central place that gets changed. When I set it up, usually have the version number set based on the time and date of the build, that way it gets updated automatically every release. Commented Sep 5, 2017 at 11:08
  • @StephenOstermiller Yeah in a CMS system that would be straightforward. Unfortunately im managing a hard coded website, which is using grunt in my dev environment for some static templating and JS + CSS minifying etc. Is there anything else that could be done server side such as setting a new apache rule ?
    – sam
    Commented Sep 5, 2017 at 16:28
  • Are you using a CMS or CDN services? You might want to look into 'cache purging' Commented Sep 5, 2017 at 17:17

1 Answer 1

2

I agree with Stephen that "cache busting" is the way to go.

Is there anything else that could be done server side such as setting a new apache rule

You can use the apache rewrite module (make sure mod_rewrite is installed) to map a URL name starting with something common and map it to an actual file.

For example, you can use a rule like this in your .htaccess:

RewriteRule ^path/to/imagename-([0-9]+).jpg$ /path/to/image.jpg [L]

In this rule, if someone enters http://example.com/path/to/imagename-12345.jpg, then the file /path/to/image.jpg is loaded and the browser processes the image. the '([0-9]+)' means any number, and any number of digits. This can represent the version number. So requests to http://example.com/path/to/imagename-1.jpg and http://example.com/path/to/imagename-2.jpg will cause the server to load /path/to/image.jpg but the client browser won't know this. Theres tons of tutorials online on how to write regular expressions for apache.

Now that you got that down, you can do the same thing to your HTML files and other files. This rule in .htaccess is an example:

RewriteRule ^path/to/htmlname-([0-9]+).html$ /path/to/html.html [L]

Then the only changes you need to make in your code are all references to the assets.

I'd personally recommend a server side language and set variables to your asset files so that you only need to change the reference once, not 100 times.

For example, consider this HTML fragment:

<p>This is <a href="bones.html">a bone</a> and 
we got lots of <a href="bones.html">bones</a> so
check out our <a href="bones.html">bones</a> today
or check <a href="bones.html">bones</a> tomorrow.</p>

Four links go to the exact same HTML file and it would be a pain to replace them all one by one. Now consider the same fragment in PHP:

<?php
$url="bones.html";
?>
<p>This is <a href="<?php echo $url; ?>">a bone</a> and 
we got lots of <a href="<?php echo $url; ?>">bones</a> so
check out our <a href="<?php echo $url; ?>">bones</a> today
or check <a href="<?php echo $url; ?>">bones</a> tomorrow.</p>

Now here, all you have to do is changes bones.html once and the $url variable will match the new value right away.

** UPDATE **

Thanks to a comment and an overnight brain fart, I just realized that It would be much simpler to write rules to divert file requests of the same filename but different version numbers to the same file. I edited my answer to reflect this.

2
  • 1
    Your rewrite stuff makes no sense to me. Shouldn't you be leaving out the $1 so you can change the number without changing the original file? Otherwise the rewrite isn't doing anything meaningful. Commented Sep 6, 2017 at 17:59
  • Yes, I was over-thinking. It actually does make sense not to include references in the resulting URL. Commented Sep 7, 2017 at 1:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.