Post banner for Building a cost-effective, globally distributed website for remote jobs

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.

Background

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.

The Goal

Build a competing job site that could not only succeed, but also be of value to the users who accidentally visit it.

The Challenge

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.

Potential Solutions

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.

The Change

I had numerous problems with the MVP. It was bloated with Google Fonts, javascript libraries, too many large images, etc, etc. There were also numerous issues with functionality such as a poor VueJS auto-complete plugin and issues with mobile navigation not working a lot of the time. Rather than pick apart each little problem, I decided to do a complete minimalistic rebuild. Instead of a framework like Bootstrap, I used only CSS styling that I actually needed in the site. Instead of jQuery or javascript libraries, I wrote vanilla JS for the functionality I required. Instead of Google Fonts, I opted for system standard fonts. Finally, instead of using icon fonts, I built a single sprite which would contain all of my icons.

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.

Hello CloudflareĀ®

Cloudflare has been doing some amazing things since their initial launch and I've been a long-time paying customer. One of my favorite new features: Cloudflare Workers. Cloudflare Workers allow you to write javascript which it will execute and return results directly to the browser. This is deployed on all of their edge servers which means you can put your content where your visitors live at no additional cost.

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.

The Benchmarks

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.4s load time from Dallas, USA
  • < 0.5s load time from Vancouver, Canada
  • < 0.5s load time from London, UK
  • 0.5s load time from Mumbai, India
  • 0.5s load time from Sydney, Australia
  • 0.6s load time from Hong Kong, China

Conclusion

As with any website, it's never completed but this is sure an amazing milestone of which I am extremely proud.

Credits

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.