New portfolio site is in the works @ lukemackenzie.dev 👀

Font Size:

High Contrast:

Accessible Font:

The Magic of Gatsby

Feb 23, 2020

It doesn’t take long to realize the power of Gatsby. Getting a site up and running is effortless and it’s blazing fast, as promised. After a couple months of using Gatsby, I mentioned to a friend how developer friendly and performant it is but found myself completely stumped when he asked, “How is it so fast?”. I quickly realized that I really had no idea what was happening under the hood to achieve such speeds. Embarrassed by such inexcusable ignorance, I set out to demystify the "magic" of Gatsby and I'll share what I've learned so far.

But first, in case this is the first you’ve heard of Gatsby, let’s quickly look at what it actually is. To learn more, I definitely recommend reading through their docs.

What is Gatsby?

In one sentence, Gatsby is:

A progressive web app generator that generates static assets but becomes a dynamic single page React app when it hits the browser.

Let’s break that down:

A progressive web app (PWA) generator

In short, this means our end result will be a website with an app-like feel and experience. Additionally, unlike native apps, version fragmentation isn't something we have to worry about since all users will run the same version of your website’s code.

Generates static assets

When you run gatsby build, the resulting folder (called public) contains completely static assets. As such, Gatsby sites are incredibly easy to deploy, especially with great platforms like Netlify. If you haven’t given Netlify a try, I highly recommend you check it out.

Becomes a dynamic single page React app when it hits the browser

You may sometimes hear Gatsby being referred to as a static site generator but that’s certainly selling it short. I’ll go into more detail on this below but for now just understand that while only static assets sit on the server, once the files hit the browser they become a regular React app. As such, we can still have dynamic features like search, authentication, forms, comments, etc.

Now that we have a high-level understanding of what Gatsby is, let’s dig into what makes it so great.

1) Build time server-side rendering (SSR)

Essentially this means that when you run gatsby build, HTML content is statically generated using React DOM server-side APIs. How? Gatsby starts up a Node server (hence “server-side rendering”) that processes your site and compiles it into static files. During this step, it creates a GraphQL schema, fetches data by executing your queries, and then renders each page’s HTML. Since this is all done at build time, when the site is deployed it doesn’t need to run with server-side processes because everything has already been gathered up and compiled by Gatsby.

If this is still a bit confusing, perhaps a quick comparison with Create React App (CRA) will help.

The big difference between a CRA app and a Gatsby app is that a CRA app requires JavaScript to parse, render, and eventually produce HTML to the DOM. As such, any users with JavaScript disabled will see something like this:

If you’ve used React, you’ll know this happens because essentially the only HTML being returned from the server is a ‘div’ with an id of ‘root’ (<div id="root"></div>). Non-Gatsby React apps, like those built with CRA, rely on client-side JS to create all the markup, which of course takes time and increases time to interactive (TTI).

Gatsby apps on the other hand do not require JavaScript to run. Users of your site are served the full HTML markup of your page. This results in a faster loading site and a lower time to interactive. An additional benefit of this is improved SEO, as search engines can more quickly and reliably parse your content and meta tags. If you care to learn more about how your SEO results can vary depending on how your page is rendered, I found this article very helpful.

2) Route-based code splitting

Gatsby utilizes Webpack to perform code-splitting and is smart enough to distinguish app-level dependencies. In other words, Gatsby does its best to figure out how your dependencies are being used (i.e. globally or route-specific) in order to ensure each route (ex. /about) is only downloading the necessary JavaScript to make the page functional.

3) Use of modern APIs

Three of the main browser APIs Gatsby uses under the hood are:

  1. IntersectionObserver
  2. Link rel=”prefetch”
  3. Srcset

IntersectionObserver / Link rel="prefetch"

The Gatsby team provides us with a super helpful and powerful component called <Link/>, which we can use for navigating internal links. If you look at the code for this component, you'll see IntersectionObserver being used to register an idle prefetch as soon as the link enters the viewport. Then when the link is hovered, a fetch is used to send a high-priority, non-idle request for the resources. Most of the time the prefetch has already made the resources available in the background, making page navigation feel seamless and confusingly fast.

As if that isn't amazing enough, Gatsby also detects network information like type of connection and will disable preloading in certain circumstances (ex. slow connections) to save data.

Srcset for Responsive Images

Another incredibly helpful component Gatsby provides us is <Img/>, which they call 'gatsby-image'. When you use gatsby-image you get:

  • Responsive, optimized images by using several media queries to load the smallest image that matches your device. This ensures mobile users aren’t downloading desktop size images.
  • A base64 blurred image loaded by default. This has two wins: 1) Larger images outside the viewport are not requested until they’re needed, and 2) The blurred image is in a container with the same dimensions as the real image—therefore, no jumping when the image loads!
  • An IntersectionObserver that swaps the base image for the larger image when the image is in the viewport.

Back Home

Luke MacKenzie2024