DEV Community

loading...
Cover image for My misadventure with Cloudflare Workers and Vue Serverless Side Rendering

My misadventure with Cloudflare Workers and Vue Serverless Side Rendering

divporter profile image David Porter ・3 min read

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. Not satisfied with that explanation? Here is a very good explanation

What we're trying to achieve

Previously I'd written a post on Vue SSR with Lambda@Edge

There it was suggested I try with Cloudflare Workers. It was actually very easy to setup a Workers Site 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 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, the engine that runs Chrome and Node.js among others.

Since Vue 2.5 a simple SSR module 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 to bring these features back in.

Hurdle 2 - App size

Cloudflare Workers are designed to be light and very fast, so Worker scripts are limited 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.

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).

Discussion

pic
Editor guide
Collapse
oguimbal profile image
Olivier Guimbal

The 50ms limit is only counting actual CPU time. You can wait requests taking as much time as you wish, the waiting time will not be taken into account in the 50ms timeout.

For instance, here is a prototype of one of my side projects which runs an SSR Nuxt.js on Cloudflare Workers.
Requests used to populate this are taking far more than 50ms.

Moreover, having bundles that weight more than a MB for something that requires SSR looks like a codesmell to me. But that's a matter of opinion ☺️

Collapse
divporter profile image
David Porter Author

Possibly, in my experience it doesn't take much effort to blow out React and Vue apps. When I have time I'll see if I can trim my app down which will be a useful exercise regardless.

Collapse
dreaminder profile image
DreaMinder

Actually, there's an existing solution, but let's just hope that there will be a way to make it work without patches and hacks in the future: github.com/frandiox/vitedge