Jump to content

Automatically Versioning CSS, js, image files


Recommended Posts

I was reading the HTML5 Boilerplate .htaccess file (like you do), when I came to the bit about filename-based cache busting.

TL;DR Resources used by a web page that will rarely change (js, css, images) should be given an 'expires' date well into the future to take advantage of browser (and possibly proxy) caching. However, when they do change, you need to tell the browser to load the new version instead of the cached version. Using query strings (eg styles.css?v=2) is not the best way.

The html5bp htaccess references a blog post by Steve Souders on this topic. The 1st comment to this post references a way to include automatic versioning for these types of resources, based on the file date. (That last link pretty much summarises the whole deal, if you haven't time to read the other links.)

The reasons why I mention this are

  1. It's an interesting subject.
  2. It seems to me to be something that could be implemented in PW for relatively little initial effort, but have significant benefits going forwards.

Now my technical ability is limited as far as implementing this goes, but that's why I mention it here. I don't know if this should be a core feature request, or a module, or what, but I offer it for discussion.

What do you think?

  • Like 3
Link to comment
Share on other sites

Yes, it's good practice to have far future expire dates. I don't think filename revving should ever be a core feature because of this though. It all depends on how you work and the frequency of when filename revisions would be needed. Some people use some kind of build tool/process that takes care of the filename revving, some might do it manually on pretty static sites where css/js/img changes happen sporadically, and others use maybe a module like http://modules.processwire.com/modules/all-in-one-minify/ which has 'automatic filename versioning' all ready to go.

Link to comment
Share on other sites

Actually what DaveP suggested would make a lot of sense as an addition to default ProcessWire .htaccess. Commented out by default, like it is in HTML5 Boilerplate, probably. I did not know that proxies dislike query strings, but that does make sense -- and I'm unlikely to be the only one caught out by this..

Taking things a bit further, options for enabling / disabling / configuring certain .htaccess settings easily during install phase could result in some very interesting possibilities. That's probably way out of scope for this particular discussion, though :)
Link to comment
Share on other sites

Rails uses MD5's for asset filenames, which is awesome, but requires some sort of build process so that the process isn't run on every page load when using PHP. We're looking to eventually build this into our MVC Boilerplate, as cache busting is a bit of an irritant.

  • Like 1
Link to comment
Share on other sites

  • 11 months later...

A quick update: we've added a manifest for cache busting of assets via our generator and boilerplate. Assets in development are served as is, production assets are all MD5'd with references stored in a manfiest in /assets/rev-manifest.json

If the manifest doesn't store a reference to an asset obtained via $this->assets('path/to/asset.ext') then it will simply serve the asset as specified in that helper.

This means the manifest is completely optional.

The manifest is generated via gulp tasks generated via our generator. The default gulp task will watch assets relevant to being revisioned, and keep the manifest updated as you work.

ProcessWire Boilerplate: https://github.com/fixate/pw-mvc-boilerplate

ProcessWire Generator: https://github.com/fixate/generator-fixate-pw

Link to comment
Share on other sites

  • 5 months later...

A couple of ways I have dealt with static file versioning in PW:

1. Use AIOM+ for your CSS and JS files. AIOM+ is sensitive to what is contained in your files though - I got an error when my CSS contained a background image path to a PHP script (for generating translucent PNGs for older browsers that don't support rgba colours).

2. A function that renames static files according to the last modified time (adapted from this article).

Include somewhere before your template head is generated...

function autoVer($url){
	$name = explode('.', $url);
	$lastext = array_pop($name);
	array_push($name, filemtime($_SERVER['DOCUMENT_ROOT'].$url), $lastext);
	$fullname = implode('.', $name);
	echo $fullname;

Use as follows for your CSS and JS...

<link rel="stylesheet" href="<?php autoVer('/site/templates/css/mystyles.css'); ?>">
<script src="<?php autoVer('/site/templates/js/myscript.js'); ?>"></script>

Add to your .htaccess, after "RewriteEngine on"...

# Versioned static files
RewriteCond %{REQUEST_FILENAME} !-s
RewriteRule ^(.*)\.[\d]+\.(css|js)$ $1.$2 [L]
  • Like 5
Link to comment
Share on other sites

  • 8 months later...

Caching over and over again..don't getting it ^^

Took some cache headers from h5bp but in my tests AIOM won't do anything when changing content of one of the files, am I doing something wrong?

autoVer from Robin coupled with the cache busting from h5bp works so far..

now I noticed Pragma and Cache-Control are set to no-cache on the request and I have no clue where this is coming from, searched thru all files, checked http-chost.conf and changed php.ini to session.cache_limiter = public (local MAMP)

and I read chrome dev tools would say "from cache" for file size, but it's always showing the file size instead and looks like its getting from server not cache..

Any idea?

Link to comment
Share on other sites

  • 1 year later...

I know this post is old, but I would like to revisit this discussion.  I would like to implement the static file caching https://github.com/h5bp/html5-boilerplate/blob/master/.htaccess using a similar technique https://nystudio107.com/blog/simple-static-asset-versioning

This covers caching theme assets(theme js, theme css, theme images) really well, but how do we handle making sure that links to user uploaded files(ex. pdf files) within our webpages always show the most current version when caching is available?  We don't want any existing internal/external links to our pdf documents break.

If I upload and replace a privacypolicy.pdf to my page, I can't wait a month or a year before the cache expires before the website user will see the new updated pdf. How do you typically handle that problem?

Maybe there is a way to only cache your theme's files, but not your user uploaded files?

  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...