Should you use GatsbyJS?
Tags: react, gatsby
Published: 2020-01-03 14:03:37

<!-- wp:paragraph -->
<p><strong>TLDR;</strong> Gatsby is good for websites that need to be fast and require high visual fidelity (like react portfolio sites), but worse than NextJs for web apps and much slower to work with than a Web Builders/CMS if all you need is a basic static site.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>For my current website, I decided to use a React-based framework called Gatsby. Now that I have finished my website to the point where I am relatively happy with it and it's fullfiling what I set out to build it for (notice I didn't say it was finished: a website is never finished), I find it adequate to write a short review of my experience!</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3>What is Gatsby? A Quick Overview</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Gatsby was initially described as a static site builder for React, but this description has been retracted by the developers. This is because Gatsby is more like "Create React App" (CRA) on steroids. Indeed, you can build anything with Gatsby that you can build with CRA, but it also adds some static site generation features, similiar to the popular framework NextJS. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>To be specific, Gatsby will render your React views to static HMTL files that get sent to the client on the first request, meaning the site is still usable with JavaScript disabled (unlike with vanilla React) and the client does not have to do the heavy lifting of assembling the site with JavaScript. This has also been linked to improving SEO and performance, since the site can be rendered much quicker on initial load. However, Gatsby goes beyond this and also offers some plugins that allow for post build optimisations, when the website is compiled into static files. One of these key features is smart image processing, which reduces the need of an expensive third party cloud offering that provides a similiar service.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3>My Requirements</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>As with anything, it wouldn't be fair for me to call this "the end all be all" review. I obviously had some hopes and expectations that I wanted to fulfill when using the framework, which were based on some basic research. As a result, I will be basing my review and experiences on my opinions, or specifically on how I felt Gatsby performed when applied to my particular use case. Here  is a breakdown of what I expected when starting to work with Gatsby:</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul><li>A fast, static website (this was the most important thing!)</li><li>Good developer experience</li><li>Being able to develop quickly</li><li>Improve my React abilities</li></ul>
<!-- /wp:list -->

<!-- wp:heading {"level":3} -->
<h3>Each Main Feature in Review</h3>
<!-- /wp:heading -->

<!-- wp:heading {"level":4} -->
<h4>Data Fetching is easy, but REST support is poor</h4>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>One of the powerful things about Gatsby is it's pre-compilation data fetching. Using a file referred to as "Gatsby Node", the user can query to various data sources and pass that data to the JavaScript views that Gatsby creates. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>For example: my blog's posts are hosted on a wordpress server. Through the Gatsby Wordpress plugin and the Wordpress GraphQL API, I can connect the two and query my posts to the Gatsby Node file. From there, I can use methods like "createPage" to generate a new page via a React component and pass it the data for a given blog post as a JavaScript object. Gatsby then builds each page to static HTML, meaning I never have to make a database or api query when the user requests to see a blog post - this is a significant performance improvement. As an example, here is how I fetch the wordpress blog posts from my Gatsby node file:</p>
<!-- /wp:paragraph -->

<!-- wp:html -->
<pre><code class="language-javascript">graphql(`
          {
            allWordpressWpBlogpost(sort: { fields: date, order: DESC }) {
              edges {
                node {
                  content
                  date(formatString: "DD/MM/YYYY")
                  title
                  featured_media {
                    localFile {
                      childImageSharp {
                        fluid(maxWidth: 500) {
                          base64
                          aspectRatio
                          src
                          srcSet
                          srcWebp
                          srcSetWebp
                          sizes
                          originalImg
                          originalName
                        }
                      }
                    }
                  }
                  excerpt
                  tags {
                    name
                  }
                }
              }
            }
          }
        `)</code></pre>
<!-- /wp:html -->

<!-- wp:paragraph -->
<p>The data in Gatsby Node is handled using GraphQL, making it easy and convenient to assemble data from many different sources (provided they have a GraphQL API). REST could also work, but its not really as integrated with Gatsbys other features and little to no documentation or plugins. This is a bummer, because setting up a custom REST endpoint is still much easier than setting up GraphQL at the time of writing for this review. In addition, obviously there are still many data sources that do not support REST out of the box.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Another method that allows us to fetch data is called "static queries", which is just used as a wrapper for normal GraphQL query and then assigned to some variable within the scope of the React hook. Now, I no longer need to query blog data from the Node file, since I can do it in the post component itself - you might think (as I did)! The problem is: we can't pass variables to these static queries, limiting their use - most of our data fetching will have to be done in the Node file. Also, if you were hoping to make static REST calls, you are going to be disappointed.</p>
<!-- /wp:paragraph -->

<!-- wp:html -->
<pre><code class="language-javascript">const data = useStaticQuery(graphql`
    query {
      linkinLogo: file(relativePath: { eq: "linkedin-icon.png" }) {
        childImageSharp {
          fluid(maxWidth: 300) {
            ...GatsbyImageSharpFluid
          }
        }
      }
    }
  `)</code></pre>
<!-- /wp:html -->

<!-- wp:heading {"level":3} -->
<h3>Image Processing is Powerful, but inconvenient</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>A core feature of Gatsby is its image processing capability. By querying the image with GraphQL, you can convert your image into a "fluid" format that will adjust to the size of its container. That image is first sent as a low resolution image for improved performance to reduce load time, then upscales within the client using a fancy fade-in animation. This completely avoids images that pop into the view, potentially shifting content, since there is no latency on the low resolution images.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>While the image processing results are great, using them is pretty inconvenient. Having to query each image with GraphQL is annoying, because the returned JSON is always a heavily nested JavaScript object (usually 3 to 4 sub objects) - this feels like unnecessary boilerplate, especially because usually you are only interested in one of the values within the object (the actual fluid image that is returned). For example, if all I want is to access the processed image on the first wordpress blog post, I got to access it like this: </p>
<!-- /wp:paragraph -->

<!-- wp:html -->
<pre><code class="language-javascript">allWordpressWpBlogpost.edges[0].node.featured_media.localFile.childImageSharp.fluid</code></pre>
<!-- /wp:html -->

<!-- wp:paragraph -->
<p>In addition, the processed images can only be used in a special wrapper components provided by Gatsby. These take up the space of the parent component and don't behave like normal images from HTML. For example, when defining a fixed dimension for the Gatsby image component, the entire image will simply disappear.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":4} -->
<h4>Hosting with Netlify and similar Services is dead simple</h4>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>The title says it all: services that automate deployment by hooking up with your git are great with Gatsby. Takes almost no time to get up and running, especially if all of your data fetching is done during compile time since your site is almost risk-free of running into annoying problems with APIs and such. Add, commit, push - and have little to no concerns that your site will go down or run into problems.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":4} -->
<h4>The Plugin System is Great</h4>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Gatsby offers a large number of community built plugins. These plugins range from support for third party services, to optimizations for commonly used React libraries (the most common being React Helmet) that leverage the static rendering of Gatsby. It's all done via a single file, each plugin is defined with a simple JavaScript object that is used to define some of the (usually) pretty straightforward parameters (so there is no webpack-like chaos going on here).</p>
<!-- /wp:paragraph -->

<!-- wp:html -->
<pre><code class="language-javascript">{
      resolve: "gatsby-source-wordpress",
      options: {
        /* The base URL of the Wordpress site without the trailingslash and the protocol. This is required.
         * Example : 'gatsbyjsexamplewordpress.wordpress.com' or 'www.example-site.com'*/
        baseUrl: process.env.GATSBY_API_URL,
        // The protocol. This can be http or https.
        protocol: process.env.GATSBY_API_PROTOCOL,
      }
}</code></pre>
<!-- /wp:html -->

<!-- wp:paragraph -->
<p>My only problem with the system is that I found it to be quite confusing when to use a plugin or simply try to import and use the node module as usual. It can also lead to some confusion when using a third-party library and it isn't working, only to realize that Gatsby requires you to install a plugin for it to work properly with the serverside rendering. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Heads up, although this was not a problem I faced: because of the compilation process, the headers of the Gatsby index.html file are reset each time. If you rely on importing something this way (like a remote CSS file), you will need to hope that a plugin exists or forced to write your own!</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3>My biggest Problem with Gatsby</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>So after that feature review, you might be thinking: "well, that's all pretty decent, isn't it?" - and I'd agree! Here is my issue though: I'm not exactly sure who this framework is for. Obviously, React developers who want to build slick, fast portfolio sites are going to love this and perhaps this is the target audience. But beyond that, it can be hard to identify how Gatsby would be more suitable for a given use case than other options.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>For example: the small, local business owner who might be interested in a a fast, static website is probably not going to bother learning React or hiring an expensive consultant with that skillset just to get a web presence. Tools like shopify, WordPress or other web builders are much cheaper, easier and faster options for this group of people. The truth is that even a lot of developers opt for these options over coding their sites from scratch, simply because of the fast speed (I found that developing with Gatsby is not really much faster than using "create-react-app") and lower hassle of getting that site up and managing it.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Then there is the bigger, enterprise businesses or smaller, independent SASS providers. These certainly have interests in leveraging cutting edge technologies that single page applications and progressive web apps provide. They are also able and willing to spend that extra buck to hire professionals for having that extra speed and customization. The big problem: NextJS also offers static site rendering and while it does not provide many of Gatsby's performance optimization tools, it does have an advantage that is extremely significant. This advantage is that unlike Gatsby's data fetching tools, which are not very dynamic, NextJS allows user to inject data into the static build process on the fly, which is ideal for web platforms on which the data is constantly being manipulated by user activity and other forces. Gatsby takes a long time to compile and spit out the static files, whereas NextJS is built to allow for this dynamic data insertion.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2>Verdict</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Overall, I am happy with how <a href="https://byteschool.io/">my website</a> turned out and enjoyed working with Gatsby. The site is fast as promised, obtaining good scores for both PC and mobile on google speed tests. As aforementioned, I don't see Gatsby offering much of a value proposition to people hoping to use it commercially, but I think that paradigm shifts, like PWA becoming a standard that customers will begin to demand from their sites or an increase in the popularity of Gatsby themes leading to a much faster development workflows, could easily help Gatsby overcome some of the competitors it is facing in various areas. I'd also love to see a future where we can just plug in a normal image tag and have all those image processing features out of the box. Maybe that is a bit idealistic or something left to the browser creators/large companies, but it would be a huge improvement over the current workflow nonetheless. The same applies to how limiting some of the static data fetching capabilities are. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Besides these flaws, I learned a lot from building my first Gatsby site and might have a look at it again in the future, perhaps with some of these aforementioned changes. I'm giving it a 7/10, 4/5 stars, "pretty deece" - I think you get the idea. Thanks for reading this review, hope to catch you for the next one!</p>
<!-- /wp:paragraph -->