How do web frameworks implement asset fingerprinting?
In the past few weeks, I have been working on asset fingerprinting for C-3PO. If you don't know what that is, the Rails guide explains fingerprinting quite well.
I began to doubt my approach and thus looked at how other web frameworks are doing it. Spoiler: I've chosen a different path than the rest. We'll see if I've barked up the wrong tree.
My approach
First of all, the difficult part isn't the fingerprinting part, but the replacement of the corresponding references in HTML. I naively went the route of replacing references in a post-generation step: After the site has been generated, C-3PO iterates through all HTML files, parses them with Jsoup, selects all <link rel="stylesheet" href="...">
tags, and replaces references like href="/css/main.css"
with href="/css/main.6180d1743d1be0d975ed1afbdc3b4c0bfb134124.css
.
Having asset references being replaced magically is nice, but what are the challenges of this approach?
One is to cover all sorts of ways HTML references assets. For stylesheets, it's pretty simple. The only way to include an external stylesheet in HTML is to use the <link>
element. What about images? We all know <img src="...">
. But there's also the imgsrc
attribute, and there's the <picture>
element, and so on.
The usual approach is different
I began to worry that my approach would become a never-ending story, which is why I started to look at other implementations. Long story short, all frameworks, static site generators, and tools I looked at require using some special asset referencing syntax.
For example in Rails, you'd write <%= image_tag "icons/rails.png" %>
instead of <img src="icons/rails.png">
.
From a developer perspective, it's easier to implement. I suppose implementations are more efficient than mine as well because asset references are most likely being replaced during template processing. But my approach has upsides as well. You don't have to touch your HTML, and you don't have to worry about forgetting to use any special asset referencing syntax.
Right now, my implementation is work in progress. I can easily imagine that there are some roadblocks ahead, rendering my approach impossible. I guess the only way to find out is to try.
Links
For the record, here is a list of resources on how fingerprinting works in other web software: