DEV Community

Cover image for Why I Use Gatsby for My Website
Will Harris
Will Harris

Posted on

Why I Use Gatsby for My Website

Originally posted on Will's blog


I built my personal website using React and Gatsby. Partially this was to give me the opportunity both to learn a new tool (Gatsby) and to practice with GraphQL.

Recently I stumbled across this blog post listing things the author would "like younger developers to think about."

Many of the points in the article seem to bemoan the widespread use of front-end frameworks in web development. I can sympathize with this point; as the author says, "sometimes a website is just a website."

However, I do think that there are good reasons for using React and Gatsby—or other static site generators—to create websites. I want to use this post to explore some of my reasons for embracing Gatsby.

I also want to encourage anyone to challenge me on these reasons. I use Gatsby because I genuinely think it is the best tool for my use-case, but am always open to learning better ways of doing things.

Image optimization

Images account for a significant portion of the size of most websites. Because of this, optimizing images can greatly improve a website's performance. The fewer bytes to download, the faster the browser can get to rendering content on the screen.

Best practices for performance across a range of devices call for multiple image sizes and resolutions. We could manually create different versions of every image that we use on a website, but this adds a lot of duplicate work for every image that we include. Another downside of the manual approach is the added bookkeeping involved in ensuring that all of the images get optimized before they make it to production.

Gatsby makes image optimization much easier, harnessing the power of build plugins and transformers to eliminate most of the manual work.

Gatsby sources data using source plugins, which allow the developer to pull data from different sources. gatsby-source-filesystem sources data into our application from the project's local filesystem, creating File nodes in Gatsby's GraphQL API. Gatsby applies various transformer plugins to these File nodes, turning them into various other types of nodes. For image processing, the gatsby-transformer-sharp plugin takes supported image files and creates ImageSharp nodes from them.

These ImageSharp nodes can then be manipulated by the Sharp image processing Node.js library to help with image processing and optimization. We perform these manipulations with GraphQL queries in Gatsby, which allow Gatsby and Sharp to perform all of our required optimizations while building the final static site. This is where we save a ton of work compared to optimizing images manually. We only need to configure how we want our images optimized, and Gatsby handles the rest.

Gatsby also ships an image component that is designed to work well with Gatsby's GraphQL queries. It is optimized specifically for fixed width/height images and images that stretch to fit full-width containers.

The gatsby-image component automatically helps with image optimization in several ways. It:

  • Loads the optimal image size for a given screen size, using the srcset property on a picture element to load the correct image size for the current viewport.
  • Holds the image's position in the document with a placeholder so that the page doesn't jump around as images load.
  • Uses either a "blur-up" effect or a "traced-placeholder" SVG to show a visual placeholder while the full image loads.
  • Lazy loads images, reducing bandwidth and load time.
  • Can convert images to the WebP format if it is supported by the browser.

All of these features are "batteries-included" with the gatsby-image component, saving the developer a ton of manual image optimization work.

No Backend / Moving Parts

Setting up a "traditional" website is a fairly complex process. From provisioning VMs to run instances of a server-side app, to configuring Docker images to ensure a consistent environment, to configuring auto-scaling solutions like Kubernetes. There are a lot of moving pieces to keep track of.

And if we want to deploy any changes to our site with this structure, it involves deploying a completely new version of the site. We'd have to spin down existing versions of the service, spin up the new version, and deal with any issues that might pop up during the process.

Gatsby simplifies this process by building websites as static HTML files which can be hosted on a CDN, getting our content as close as possible to our users. We can then configure a continuous integration (CI) system to rapidly build and deploy code updates to the CDN.

My site is hosted on Netlify, which allows me to use a GitHub repository as my CI system. If I want to publish a new version of the site, all I need to do is merge a pull request into my main branch. Netlify is constantly listening for pushes to that branch—as soon as changes are noticed, a new version of the site is built with Gatsby and pushed to the CDN. Typical deploys for me right now take about one minute.

Both approaches can result in robust, performant websites. However, deploying and hosting static content via CDN has far fewer moving pieces and completely removes the server management aspect of developing a website.

Build Optimizations

Gatsby sites are built in React and then built into static HTML files by Node.js processes. The process of converting pages and content on the server into HTML is called server-side rendering (SSR), and it's nothing new.

Developers have been rendering HTML pages on servers for many years. Previously, however, sites would use languages like PHP on the server to fetch data from databases, in response to user requests, and compile it into an HTML document to send to the user.

With Gatsby, all of the SSR magic occurs during the build process. This build process has quite a few steps, but as a quick summary:

  • Gatsby checks for data sources defined in the gatsby-config.js and gatsby-node.js files. It then creates Node objects from the data it finds in these sources.
  • Gatsby infers a GraphQL schema from the Node objects created in the previous step. This is where Gatsby forms the data layer for our application, making all of the data brought in from our sources available in a GraphQL API.
  • Gatsby creates pages from the React components in our site.
  • GraphQL queries from our React components are extracted from our components and run against the GraphQL layer, providing data for all of the HTML pages.
  • Static files are created for all of our pages, with all data bundled alongside our views in the public directory.

The resulting HTML files created by Gatsby also use modern browser APIs to maximize performance, resulting in crazy fast websites.

Gatsby harnesses the IntersectionObserver API, which conditionally performs actions when elements enter the browser's viewport.

Specifically, in Gatsby IntersectionObserver is implemented in the Link component for routes internal to the site. The behavior has two parts:

  • An IntersectionObserver is registered for all Link components. This registers an idle prefetch request for each Link's resources, allowing the browser to automatically start loading those resources as soon as the browser is in an idle state.
  • On a mouseenter event for any Link component, a fetch request is fired with a non-idle request for the Link's resources.

In combination, these two techniques almost guarantee that internal page data will be prefetched, which makes page loads on our site feel instantaneous.

Plain Text

One additional benefit I've found in using a system like Gatsby for my writing is the ability to keep all of my data in plain text markdown files.

As Dave Thomas and Andy Hunt write in The Pragmatic Programmer:

The problem with most binary formats is that the context necessary to understand the data is separate from the data itself. You are artificially divorcing the data from its meaning. The data may as well be encrypted: it is absolutely meaningless without the application logic to parse it. With plain text, however, you can achieve a self-describing data stream that is independent of the application that created it.

By keeping all of my writing in markdown files, I guarantee that I'll never be dependent on a specific piece of software to use my content. I also can harness the inherent semantics of markdown to generate HTML elements from my writing.

Gatsby uses the gatsby-transformer-remark plugin to make the contents of my markdown files available in GraphQL, allowing me to inject the generated HTML into my blog posts at build time.


This is by no means a complete list of reasons for choosing static site generators like Gatsby for building modern websites, but I hope it can at least be helpful for anyone who hasn't yet jumped into the Gatsby ecosystem. It can be intimidating at first, but the time spent learning the system is well worth it for the speed of the final site. The developer experience building and maintaining a Gatsby site is also excellent.

Do you have other static site generators or other approaches to building websites that you're crazy about? Tweet me @will__tweets and let me know, I'd love to hear about it!

Top comments (10)

Collapse
 
katiekodes profile image
Katie • Edited

To the original author's point, you can use gatsby-plugin-no-javascript to make Gatsby render mere HTML production output a lot like what a more "traditional" SSG like Jekyll / Hugo / 11ty would render, while still getting a lot of the advantages of its rich plugin ecosystem such as gatsby-image.

I wish site builders like Wix would give you that sort of option. Like, help you lay out the CSS and help you do data entry, take care of optimizing images for you, then go away in production. But then I guess they wouldn't make any money over-analyzing you and your visitors.

I'm still choosing an SSG for my side project that's "just a website" (no need for client-side JavaScript except perhaps a toggle menu), but I'm considering "Gatsby with the extra JavaScript output turned off in production" for this reason.

That, and the fact that the extra JavaScript in "develop" mode opens up additional CMS possibilities with respect to live previews.

Collapse
 
jhelberg profile image
Joost Helberg

I use an xslt (> 1000 lines) script for transforming html to ... html, but then organised by titles and cluttered with menu's, css and other stuff. Html in and html out. Very fast and accepts all legit html. Also adds some javascript for small screens. The JIT version uses the 404 handler of apache and is very fast.

Collapse
 
patarapolw profile image
Pacharapol Withayasakpunt

You should be careful for mobile. Not only loading time,

but also word wrapping on smaller screens.

Collapse
 
will_devs profile image
Will Harris

Hi Pacharapol,

Could you say more about what you mean here? Are you talking about the site that I linked to at the top of the post?

Collapse
 
patarapolw profile image
Pacharapol Withayasakpunt • Edited

It may not be an SEO factor, but the text is wider than the screen on mobile.

You can see that the title is wrapped but not the text.

Thread Thread
 
will_devs profile image
Will Harris

Thanks for getting back to me, I'll get on fixing that tomorrow.

Not sure how I missed that!

Collapse
 
perpetual_education profile image
perpetual . education

These are good thoughts! We used to want to build all of our sites with Ember.js for many of the same reasons - but the static bits never quite came together. So, do we get to see it? : )

Collapse
 
will_devs profile image
Will Harris • Edited

The current iteration is here :)

Collapse
 
perpetual_education profile image
perpetual . education

Its so pretty! There are no images! We expected it to be image heavy. Why do you think - after all of that static-ifying - that the performance is still 74/100? (oh - actually - there are images / but they are out of ratio and distorted. We're interested in all of the points in this article - but it's a hard sell for a site that could be built with just some PHP and HTML. We'll be reading it again! and thinking about it some more.

Thread Thread
 
will_devs profile image
Will Harris • Edited

Thanks for taking a look!

I've gotten good performance metrics on all of the testing that I've done, it's interesting that you're seeing a lower score.

Also worth mentioning that I'm not prescribing that anyone else make the same choice for their website. Merely laying out my thinking for making the choice that I did. :)

And THANK YOU for pointing out the squished images. That is something that seems to have happened today while I was trying to fix a mobile display issue, and should (hopefully) be fixed now.