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:
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:
- IntersectionObserver
- Link rel=âprefetchâ
- 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.