/ Performance

Remove render bottlenecks with Fly

Deep in the nethers of internetland, there's an e-commerce site that takes 22 seconds to load. The products are great, but nobody's gonna wait. There's lots of quality new traffic, but the bounce rate is astronomic. Every premature bounce is wasted marketing. The worst part? Impatient people don't buy, so sales are sliding. As a result, there's no money to fix the underlying speed issues causing all this trouble in the first place. This vicious feedback loop keeps this poor internet merchant up at night (and kills his profits during the day).

What can they do?

A typical developer's knee-jerk solution would be to rebuild the site (or overhaul the existing one) to get rid of the spaghetti code the current site runs on. After all, that's a big reason the site has become so slow. Years of neglect & hasty "fixes" have resulted in a patchwork of code that just barely gets the job done— and unfortunately, it's not a job done particularly well or quickly.

People hate slow pages.

But rebuilding or overhauling most sites is not a trivial endeavor. It requires lots of time and lots of money...two things this site owner doesn't have. Could there be a third option?

To Be Fast, You Need Clean Code...And Clean Flow

To think beyond the knee-jerk solution, first we have to acknowledge that fetching a typical modern website is a bit more involved than a single request-response loop from browser to server and back. These days, when a user requests a new site, there's a flow of data going back and forth many times: after a DNS lookup tells our browser where to go, there's a TLS handshake, server response, and then several more round-trips to get assets like images, CSS files, fonts, scripts, and other stuff to make sites look pretty & do cool things.

TLS usually requires 3 round-trips, loading third-party scripts is often slow, and a single physical server can be thousands of miles away from a user. So aside from your server's code, there could be a ton of other items slowing down your site on the users'end.

Let's investigate these other items & see how we can clean up this flow to be more efficient.

Enter Fly

As it turns out, Fly can help us dramatically reduce load times without ever touching our server's yucky code. We'll do this by enabling optimized TLS termination, loading third-party scripts from edge-servers, and smartly redirecting traffic based on user authentication.

TLS

To set up an HTTPS hostname, simply POST /api/v1/apps/<your app's name>/hostnames:

POST /api/v1/apps/<your app's name>/hostnames HTTP/1.1
Content-Type: application/json
Authorization: Bearer <your personal access token>

{
  "data": {
    "attributes": {
       "hostname": "<your_hostname.tld>"
    }
  }
}

In response, you'll get an object that includes a preview_hostname. Just create a DNS record linking preview_hostname to your hostname and you'll get auto-renewing TLS certificates terminated around the globe over HTTP/2—that means TLS handshakes will require 1 fewer round-trip, and because of Fly's global network, they'll happen closer to the user (among other nifty things).

Third-Party Scripts

Now, let's make our servers serve third-party scripts. With ga.js in the project's root directory and .fly.yml set accordingly, we can serve a script like this:

addEventListener( 'fetch', function( event ) {
    event.respondWith( async function() {
        const response = await fetch( "file://ga.js" );
        response.headers.set("content-type", "application/javascript");
        return response;
    });
});

Because of Fly's global network, not only will these scripts reach users quicker, but they'll be sent over HTTP/2 (instead of being requested by the browser over HTTP/1.1) so they'll start traveling to the user much quicker.

(Smart) Static Front Page

Because Fly is smarter than your typical CDN, we can be smarter about how we serve our site. Because our biggest missed opportunity is with new visitors, and because new visitors make up the vast majority of our traffic, we're going to use Fly to serve a blindingly-fast static front page to every new visitor. That way, new visitors can start browsing (and buying!) immediately.

We'll do this by checking the HTTP request to see if a user is logged in. If they are logged in, we'll serve them the legacy site. If not, we'll serve them a static site that looks exactly like the existing site's front page.

Once you've got static site designed & deployed, configuring Fly to serve the right site at the right time is quite simple:

addEventListener( 'fetch', function( event ) {
    
    let headers = new Headers( event.request.headers );
    
    if( headers.get( 'cookie' ) && ( ( headers.get( 'cookie' ) ).indexOf( 'login_token' ) > -1 ) ) {
        //user is logged in
        //serve the crappy legacy site
        
    } else {
        //user is NOT logged in
        //serve a (cached?) static site
    }
});

Fly works with a number of static site hosts like Surge.sh and Pancake.

That's Not All, Folks!

Now your whole site is faster for everyone—especially for first-time visitors—who are not only the vast majority of your total visitors, but the ones for whom a lightning-quick site is most critical.

Great! But these tweaks offer us another huge benefit for free: better SEO. Google ranks faster sites higher—and that's the exact metric we just improved. How cool is that?

Hooray! Not only have we made our site vastly quicker for our most important users, but we've made it easier for users to find our site in the first place (better SEO) AND we've made it more likely that they'll buy something when they do visit. All without touching any server code and using Fly's developer-friendly API to custom-configure a fleet of servers around the world to intelligently serve our site in the quickest possible way.

Try it out! Getting started is almost too easy.

Steve Jain

@m52go

http://jain.io

Steve Jain

Indie developer running 2 apps that make the high-brow a little less high. Uses JavaScript everywhere, including places it has no business being in. Recovering B2B biz developer & financial analyst.