In this post, I'm going to focus on my endeavors making remote.io a globally distributed site that loads in under one second - world-wide!
Importance of Speed
Before going into the technical bits, I want to focus on speed. Website speed is essential because it directly impacts user experience. A poor user experience means you've lost a potential returning visitor. In addition to this, Google has numerous algorithms specifically geared toward user experience. These include mobile-friendliness (this gets as granular as you have click-able sections too close together on mobile devices), initial page loading speed on desktop and mobile devices with 3G connectivity, and the time it takes to fully paint the website with all content. If any of this is poor by Google standards, not only are your visitors unhappy, but Google is going to rank you lower.
Remote.io is a job board for work-at-home / remote careers. It's built mostly from job feeds and custom filtering engines that are constantly being tweaked. It came about because I own such a similar domain to all of the other remote job sites that I was receiving over a thousand unique visitors per day to an undeveloped page with only Google Analytics. Once I saw the traffic on Analytics, I decided to research where these visitors were intending to go. Once I found that out, I knew I had a viable project ready to be built.
Build a competing job site that could not only succeed, but also be of value to the users who accidentally visit it.
The biggest challenge is that remote workers are globally distributed while most websites are not. Websites requiring functionality for displaying dynamic content need a server or serverless architecture that can process the requests and return the expected results. Both of these options leave your data mostly centrally located to at least one continent unless you want to fork out big bucks for infrastructure on the hopes your project can make serious cash. This wasn't one of those projects so global distribution of data wasn't an appealing option.
Static websites. I jumped back on the static website bandwagon when AWS S3 started allowing the serving of bucket contents directly, without having to use CloudFront. It's a great solution to build a distributed website on a highly redundant backbone. The costs are between a few cents and a couple dollars a month depending on how much traffic you receive. It can get pricey for larger content because the bulk of your fees are bandwidth usage but this is great for small HTML / CSS / JS sites.
Shortly after, I started playing around with Netlify. Netlify is huge now and has a lot of really cool features. This is the best way for entry to mid-level website developers to build and deploy a globally distributed site. Best part about Netlify is that it's free and doesn't even require a credit card. You can even have contact forms that email you at no cost but be sure to implement captcha and honeypot fields to prevent abuse or they will charge you from too many form submissions.
The Initial Choice
For this project, I intially chose Netlify. Instead of just static HTML, I decided I would use VueJS. Netlify will take a repo, run your build script, and then store and serve your built code across their global CDN - for free. For my dynamic data, I still needed processing, so I chose to use AWS Lambda for data APIs. Turning on Netlify Server-side Processing allowed it to cache the fully rendered pages and all was okay.
I had a website that was fully loaded and painted in 3 seconds and gave me a minimally-viable product.
The Speed Bump
Once the website was live, traffic immediately started to spike and I started disliking the 3 second render time on typical home cable connections. About that same time, Google told me that the site loads too slow on 3G connections and I was able to confirm a 9 second render time. In order to remedy this, something major had to change.
I now had a bare minimum site skeleton that would load drastically faster but that wouldn't solve my DOM paint time from the API loaded data.
I had received emails outlining their Cloudflare Worker Sites and Key-Value Storage and wanted to try it and this was the perfect opportunity. Within minutes, you can have a static site deployed to Cloudflare and have blazing fast response times.
My situation is a little different because I need to actually serve dynamic content. My solution was to build the site as static HTML with placeholders and then populate them with the data in real-time. The data comes out of the Cloudflare KV storage (essentially the same as a Redis cluster) which maintains a copy of your data at all of the same edge locations as your website code. In the event something happens and the data isn't there, I have it pulled from my legacy AWS Lambda endpoints, served to the user, and then stored in the Cloudflare KV cluster for future visitors.
The costs are less than renting a decent VPS at only $5 / month for Cloudflare Workers Unlimited plan which has more KV storage that I could ever use and plenty of CPU processing power for this site. Even this blog is part of my Cloudflare Worker Site.
This is where it gets great:
- I took the landing page size down from 1.11MB to 128KB (not including company logos for job listings).
- Total requests from 30 to 7 for the base site. There are extra requests for benchmarking, company logos, etc.
- Load time from nearly 3 seconds to 0.5 seconds fully-loaded!
Did I mention this is GLOBAL?
< 0.4sload time from Dallas, USA
< 0.5sload time from Vancouver, Canada
< 0.5sload time from London, UK
0.5sload time from Mumbai, India
0.5sload time from Sydney, Australia
0.6sload time from Hong Kong, China
As with any website, it's never completed but this is sure an amazing milestone of which I am extremely proud.
The motivation and intro knowledge to embark on the transition to Cloudflare Workers came from reading a few great articles that I stumbled upon in my quest. I am in no way affiliated with any of the below posts or websites.
- This got me excited enough to start the project: Deploying A Static Nuxtjs Site To Cloudflare Workers
- This is probably an even better approach than I took and one I may revisit in the near future for a rewrite: Server Side Rendering With Vue And Cloudflare Workers
- This is a fantastic article showing routing functionality for dynamic content which is better than my approach: Building a Serverless Doc Writing App Using Cloudflare Workers And KV Store
- This is a collection of various docs demonstrating some of the amazing things you can do with Cloudflare Workers: Awesome Cloudflare Workers
- Last, but certainly not least, the Cloudflare Workers documentation which contains tutorials, ready-to-use templates, and decent enough documentation to figure out what you need to know.