My misadventure with Cloudflare Workers and Vue Serverless Side Rendering
Tags: vue, cloudflare, ssr
Published: 2020-12-29 14:18:08

_In which I talk about my attempt at Vue Serverless Side rendering with Cloudflare Workers_

Just in case the lynch mob arrives I will preface this post by saying that I like the Cloudflare Workers Site concept. This post simply highlights that performing Serverless Side Rendering (SSR) with Cloudfare Workers is still quite challenging.

## **Tell me about Cloudflare Workers**
You can think of these like service workers that execute at in the cloud.  Cloudflare have hundreds of edge locations around the world and the location nearest to your user will handle that particular request.  It's very similar to [AWS Lambda@Edge](https://aws.amazon.com/lambda/edge/). Not satisfied with that explanation? Here is a [very good explanation](https://developers.cloudflare.com/workers/learning/how-workers-works)

## **What we're trying to achieve**
Previously I'd written a post on Vue SSR with Lambda@Edge
{% link https://dev.to/divporter/vue-serverless-side-rendering-with-aws-lambda-edge-1ep8 %}

There it was suggested I try with Cloudflare Workers. It was actually very easy to setup a [Workers Site](https://developers.cloudflare.com/workers/platform/sites) with very little config and zero modification to my Vue App. That was very pleasing.

For those looking to give it a go, if you have lots of assets then consider using [Backblaze](https://help.backblaze.com/hc/en-us/articles/217666928-Using-Backblaze-B2-with-the-Cloudflare-CDN) to store your many images.

## **Hurdle 1 - V8 Engine**
So the problem here is that with traditional Vue SSR, it's expected to be executed in a Node.js environment.  Cloudflare Workers run directly on [V8](https://v8.dev/), the engine that runs Chrome and Node.js among others.

Since Vue 2.5 a [simple SSR module](https://ssr.vuejs.org/guide/non-node.html) is shipped as well which is mostly environment agnostic so you can do SSR with PHP or Python for example. In essence, this renderer simply renders our Vue app to a string.  So we lose the cool features like template interpolation and injection that come with the standard Renderer and BundleRenderer.

Thankfully, in response to the challenge below a kind soul (or souls) [modified the basic renderer](https://github.com/l5x/vue-ssr-cloudflare-workers-template/blob/master/vendor/vue-server-renderer/basic.js) to bring these features back in. {% twitter 1185301603366178817 %}

## **Hurdle 2 - App size**
Cloudflare Workers are designed to be light and very fast, so Worker scripts are [limited](https://developers.cloudflare.com/workers/platform/limits) to 1 MB compressed size.  If your site is a simple one then hey, no worries. If you're running a fully armed and operational battle station which exceeds that limit then like me you're out of luck.

There are probably a few ways to get around this like slimming down our application or storing the bundled app outside of the worker (like in KV or Backblaze) and downloading it at runtime. The first is something we _should_ do anyway, but who has the time! The second won't work due to the next hurdle

## **Hurdle 3 - Execution Time**
A common feature of SSR is fetching data on the server(less) side instead of on the client.  This can also be an SSR killer if the fetch operation is slow, but let's stick with wanting to do our API fetching on the server side now. 

Worker scripts are also capped to at most 50 ms execution time.  This doesn't leave much room for latency on even a simple request let alone a more complex (ie one that requires more time to respond).  

So looking back at Hurdle 2 if we were to try to pull in our bundled app from KV, then parse it, then render the app HTML we're probably pushing it on the execution time and that's without any data fetching that may occur within the app.

## **Verdict**
The setup is easier than CloudFront and much more friendly than Lambda@Edge.  However, like my review of Svelte/Sapper (hey! Two self promos in the one post!) I think Cloudflare Worker sites are cool but just not quite there for Vue SSR. {% link https://dev.to/divporter/svelte-sapper-vs-vue-2dnk %}

SSR may not be everything, but it's the great for things like SEO and other applications crawling/scraping your site (eg Facebook crawlers don't wait for client side JS unlike Googlebot).