Right now, we hash files so we can treat URLs as ‘immutable’, and cache them for a long time.
Eg styles.a74fs3.css
can be set to cache for a year. If the content of the CSS is changed, the URL to the CSS would change.
The same would happen for resources in the CSS:
html {
background: url('/bg.8e3ac4.png');
}
However, if the background image changes, the URL above will change. And that means the content of the CSS file has changed, so the URL for the CSS also needs to change.
The user ends up having to redownload the CSS (a render-blocking resource) to find out about the background image change.
This is also a problem with JavaScript, which imports other bits of JavaScript, and references images, CSS, fonts, etc.
If the problem isn’t clear from the above, here’s a more detailed description.
Import maps solve this but only for JavaScript importing JavaScript. The solution doesn’t work for CSS, or for other resources referenced in JS.
There was a proposal to allow arbitrary fetches to be resolved via the import map using the import:
scheme, but the layering feels wrong to me. Why should CSS have to do through a JS module mapper just to map fetches from one URL to another?
I propose that we introduce “fetch maps”, which allow URLs to be mapped from one to another.
Import maps will be layered on top, but will focus on module-specific features.
<script type="fetchmap">
{
"urls": {
"/styles.css": "/styles.a74fs3.css",
"/bg.png": "/bg.8e3ac4.png"
}
}
</script>
<link rel="stylesheet" href="/styles.css">
And the stylesheet:
html {
background: url('/bg.png');
}
Now, to change the background image, only the map needs to be changed.