Foolproof Front-End Asset Cachebusting

Here’s a scenario you’re probably familiar with if you’ve done any amount front-end development. After deploying a CSS or JavaScript change and notifying the client, you hear back that they’re not seeing the updates. This is usually because their browser has the old CSS/JS cached and needs to be hard reloaded to re-download the new assets.

This isn’t too big of a deal for low-traffic sites or small changes, but what about when you’re deploying a significant change to a high-traffic site? I had a scenario recently where I was deploying a new header and navigation to a high-traffic website that had been using the old header styles for years. We’d rebuilt it from the ground up — new HTML, CSS, JS, everything — so without the new front end assets, the page looked completely broken.

Version Parameter

A common trick to force the browser to re-download assets is to add a version parameter to the query string of the CSS or JavaScript file you’re linking to:

Every time you make an update to the file, you’d update the version to a new value, which the browser reads as a new URL it must re-download to it’s cache. This is a pretty good solution, except that you have to remember to change the version every time you’re deploying updates that necessitate the browser re-download new assets.

Timestamp Versioning

One solution I’ve seen to this is using a timestamp as the asset version. This is especially helpful during development because it ensures you have the freshest version of the file on every page load:

While the timestamp method works well for development, but you wouldn’t want to use it in production since it forces the browser to re-download the assets on every page load — no bueno. Ideally we’d like a solution that only forces the browser to updates its cache when something changes, but makes use of the cache for performance reasons when it can.

File Modified Versioning

The solution is to set the version parameter to the timestamp of the last file modification for the asset you’re linking to:

Think about it — this solves all of our problems. Without any manual work, we’re guaranteed the browser will re-download our assets every time they change. And if they haven’t, the URL remains the same on as the last page load and the browser can keep its existing cache. Viola!

Integrating in WordPress

Since most of my work takes place in a WordPress environment, here’s how you’d integrate this using WordPress’s wp_enqueue_style() and wp_enqueue_script() functions:

Whatever you pass to the 4th parameter in both enqueue functions serves as the value for the ver parameter in the URLs to the asset files generated by WordPress.

Other Options

As is usually the case, CSS-Tricks has a great post listing a bunch of different methods to tackle this problem.

If you have a favorite solution, let me know in the comments.

Hosting a Podcast on Google Drive

As of August 31, 2016, Google has deprecated Drive’s web hosting features that enabled the process below to work. I’m keeping this post around for the sake of posterity, but I’d recommend finding another host for your podcast audio.


When I hosted the Young Guns Show I used Amazon’s S3 service to host the audio files for the podcast. This worked well and while the podcast was going, I had no problem paying the $10–15/month that it cost me to host the files.

Since I’ve stopped recording new episodes, traffic has dropped off some, but still to this day I find myself paying $7–10/month in hosting fees for the audio files. I’m not sure where this traffic is coming from to be perfectly honest. Maybe I still get a lot more first-time subscribers than I realize, or maybe it’s being picked up by 3rd-party podcast curation and distribution services. Either way, that adds up and since I’ve stopped recording, I estimate I’ve spent about $200 hosting the files.

This finally got on my nerves and I began to look for another way to host the files. The perfect solution would have:

  • Little-to-no cost
  • Fast servers
  • No file transfer bandwidth limit
  • An easy way to manage the files

One option I looked at was Dropbox, but because of some of the issues mentioned in this article, I opted against it. Another option was to host the files on archive.org, but as I understand it, it’s very difficult to edit or remove things from there after they’ve been added, and I wanted more control.

This brought me to Google Drive, and after some digging, I discovered it to be the perfect solution.

How to Host Podcast Audio on Google Drive

Before I start, I’m going to write this with the assumption you’re working through the drive.google.com web UI. You can probably do all of this through the app though.

Create a new folder in your drive to host all your podcasts’s episodes. For YGS, I even opted to host my iTunes artwork here as well. Right click on the folder and select Share and then Advanced. Under “Who has access” and next to “Private – Only you can access” click Change. Select “On – Public on the web” and save your changes.

Now, upload your audio files. Once uploaded, right click on the file and select Get Link. This will provide you with sharable URL to the file that will look something like this:

https://drive.google.com/open?id=0B-_jsYSK16YkYmFNSV9ybGVmelk

Take a careful look at that URL. Everything after ?id= is the ID Google Drive has assigned to that file and is critical in accessing it in a raw, usable format. So, for this file, the ID is 0B-_jsYSK16YkYmFNSV9ybGVmelk.

Copy the ID and open a new browser tab to http://googledrive.com/host/yourfileid. So, in our example case, that would be http://googledrive.com/host/0B-_jsYSK16YkYmFNSV9ybGVmelk. Opening that will redirect you to a much longer URL, in this case: https://bb10a2c23f743df5e53a94c02a17daddf6af940a.googledrive.com/host/0B-_jsYSK16YkYmFNSV9ybGVmelk. And there you have it, your podcast audio hosted on a publicly accessible, fast server, for free.

Migrating a WordPress Site from utf8mb4 to utf8

Starting in version 4.2, WordPress will attempt to upgrade its database tables from utf8 to utf8mb4. You can read more about the change on make.wordpress.org if you’re into that kind of thing, but most of the time it won’t affect you. Most of the time.

It did affect me though. I ran into an issue where I’d built a site on a development environment running on MySQL 5.5 which supports utf8mb4, but had to launch it on Media Temple’s Grid service, which runs MySQL 5.1 and doesn’t support utf8mb4. I saw a few people recommending exporting the 5.5 database in phpMyAdmin using MYSQL40 compatibility and importing that into your 5.1 environment, but when I tried it, it messed up some serialized Beaver Builder data.

Eventually I discovered that WP Migrate DB is the way to go. The free plugin allows you to export your data with URL and file paths automatically replaced, and pre MySQL 5.5 compatibility. I ran it on the development site and got an export that I was able to import directly into the live, 5.1 environment without errors or corrupted serialized data.

I’m not sure how much of an edge case my situation is, but hopefully this is helpful to someone. Any other work arounds you’re aware of?

ThemeBright

I’ve wanted to start my own WordPress theme shop for a long time… a really long time actually. On Monday I finally did it and launched ThemeBright, a theme shop that makes WordPress themes for churches. The first theme is called Restful and I’m giving away a free copy.

We’ll see how this goes, but I’m giving it my best shot.

Observations on Modern Blogging

Lately, I’ve been reading a lot of blog posts.

In fact, most of them are like this one.

One sentence per paragraph.

Or, if you’re feeling adventurous, maybe two. Like this paragraph.

As if every line was earth-shattering news that deserved a paragraph all to itself.

I understand what you guys are trying to do.

I get it.

You understand that short paragraphs are considered helpful.

You understand readers have short attention spans.

And you understand that writing long paragraphs is hard.

But I have a request.

And I’ll keep it brief.

Stop it.

Please.

It’s really annoying.

Thanks.