I have been wanting to do this for a long time, and it seems that with the newly unveiled Firebase Functions Hosting Integration... well, we still can't do exactly what we want. But we can get close!
If you follow the read the post above, you can see how we can now edit the firebase.json
redirect a URL(s) to point to a firebase function which will can build the page from markdown stored in firebase and serve that to the client.
The thing is, this happens on every GET
request for each page. Which is dumb (for a largely static page like a typical blog). We want static pages that are instantly available without needing to wait for functions to generate anything (even though that happens really fast). We can mitigate that by setting the Cache-Control
header to an arbitrarily large number with the response
object as in
res.set('Cache-Control', 'public, max-age=600, s-maxage=31536000');
Which will tell the browser to cache the result for 10 minutes, but the CDN to cache it for a year. This almost solves the problem of wanting pre-rendered, instantly available pages for all but the first hit, which will incur the render cost. Plus, the CDN can evict your cached content if it determines that there is not enough traffic to warrant storing it.
Getting closer.
But we aren't quite where we need to be. Say you publish your post and a few days later, notice a typo? Well, I think you are pretty much hosed. Your cached content will continue to be served for the rest of the year unless you do something like:
Change the URL of the Post - This is probably a bad idea, as it will tank any SEO and break links to the page that are already in the wild.
There may be a way to force the CDN to update, perhaps by augmenting your 'publish blog post' process to included a javascript GET
request with something odd in the request header, or maybe there is a way to do it with a firebase function any time the post gets updated. This is where I get stuck.
Firebase uses Google's Cloud Platform CDN which includes a mechanism for Cache invalidation, but I don't know that this is readily available from functions -- and even if it does, it still doesn't solve getting evicted from the cache.
Personally, I will probably use the setup I described with a CDN cache age limit of intermediate length. This beats my current approach of sending markdown to the client and rendering locally using (the excellent) showdown.js, which is still really fast, but does require client side javascript and a few cpu cycles.
Hopefully someone will have a solve for this (or someone at firebase can slip pushing to hosting from functions into the next release :) ). I'll update my answer if I get it nailed down.