Last updated: August 10th, 2020
đ¨âđģ Revising my MERN stack for early 2020
When I created my first MERN stack template, I had six months of React experience built upon database and data mining classes I took in college. It's now been 4 months since I open sourced my MERN stack template, and I used it for a variety of projects. Along the way, I encountered some pitfalls & searched for solutions.
đģ Ghost CMS integration
Ghost CMS hosts all my written articles. I really appreciate the Ghost web interface for editing articles in Markdown. I've always wanted to have complete control of my frontend design using React + Ant Design, with an easy way to add content to the site and migrate data in the future. I used a web application framework for React.js called Next.js. For my personal blog, TimKnowsBest.com, I wrote a GraphQL resolver for the Ghost REST API interface and dynamically generated each webpage per visitor with server side GraphQL using Apollo GraphQL. Next.js makes GraphQL queries inside of getInitialProps server side on the first page load. This is sub-optimal because we disqualify the website from the performance gains of static web hosting. Plus, if you self-host Ghost, your web server is constantly pinging your self-hosted server for data on every page visit, creating bottlenecks.
After doing some research, it seems Gatsby.js has a solution to this problem, StaticQuery (opens in a new tab). Gatsby.js is a competing web application framework for React.js. Using StaticQuery, it is possible to statically generate all the client side HTML, CSS, and JS required to display the website, which can then be deployed to any content delivery network.
Gatsby.js for content publishing
In October 2019, Ghost announced version 3 of their self-hostable CMS (opens in a new tab) with support for Gatsby.js frontends. Using the provided Github link to the Gatsby-Ghost starter kit, it is trivially easy to integrate Ghost CMS with a custom React frontend. Using Gatsby.js StaticQuery, our website is rebuilt and redistributed to all CDN nodes after every page edit on Ghost.
To gain all the previously mentioned benefits for TimKnowsBest.com, I extended this Github project, added my favorite React component library, Ant Design, and created some React Components for displaying Portfolio information, like Resume and Contact details. I open source my personal blog template for budding full stack developers to learn.
Image optimizations
Next.js is lacking in first-party image optimization support. Media I display from server side GraphQL queries on Next.js is displayed without the image optimization libraries I included in my MERN stack template. I could create a function to find and replace the default image elements with a HOC that applies the necessary image optimization HTML, but why bother when Gatsby.js includes support out of the box. This is where Gatsby.js leads, but still has much room for improvement.
I define three categories of image optimizations
- Hotlinking - Serving static assets (images, fonts, etc) belonging to another website on your website.
- CDN - Serving all static assets from a content delivery network to lower asset load latency.
- WebP - Serve PNG and JPG images as WebP on Chromium-based browsers (over 66% of the market in early 2020). WebP can save 34% file size compared to PNG and JPG (opens in a new tab).
Google's mobile data provider, Project Fi, charges $10/gb of LTE data. Without image optimizations, the production landing page for TimKnowsBest.com is 2.53 MB in size, meaning each page load costs the viewer $0.025 in mobile data fees. If I used WebP, I could save each website visitor nearly 1 cent ($0.0086).
Next.js template plans
Gatsby.js has made some improvements to its core platform that make it a better choice for my personal blog. However, Gatsby.js does not include support for an API server like Next.js. I still have plans to support my Ant Design + Next.js MERN stack template for web apps that require an API server that can scale.
CSS Module support
CSS Module support was introduced on April 22, 2015. Scoping CSS prevents many of the logic errors caused by global CSS declarations, which may be foreign to developers coming from Android and iOS app development. Why Ant Design hasn't adopted CSS module support is beyond me. Due to the lack of CSS modules support in Ant Design, I am currently comparing alternative React Component libraries, like Semantic UI & Material UI for use later in 2020.