In search for the perfect landing page - Part 2

December 7, 2020 by Michael Diez

At the end of Part 1 I mentioned that in my quest to find the perfect landing page, one that has great design and performance, I ended up redesigning my website with Nuxt.

However, my experience with Nuxt was far from plug and play (granted I was learning the framework at the same time I was redesigning my website).

So I decided to keep looking for other solutions.

I wanted to look at another JAMStack framework, one of the most popular ones, one based on React. Enter Gatsby.

I was not wrong in suspecting that just like Nuxt, learning Gatsby was going to be a rabbit hole.

With Nuxt I learned about code-splitting to deliver Javascript efficiently, Post CSS to deliver only the necessary CSS, and Lazy loading components to reduce the load on the main thread while loading the page.

I was already familiar with Vue but I had used it in an Electron app I made for a client so load time was not that important.

Here are a few wonderful things Gatsby introduced me to:

  • Styled Components
  • CSS in JS (tagged template literals)
  • CSS modules
  • HTML as functions (JSX)
  • Theme UI
  • Constraint-based design (Tailwind CSS)

I could have learned this with Next or react, or any other framework based on React.

One thing that is kind of special about Gatsby is Shadowing files. It reminds me of Child themes in WordPress.

One thing that kept me from trying React was JSX, specifically writing HTML and CSS in Javascript.

Keeping it separate is what attracted me about Vue. Conceptually it seemed easier to organize than React, but I think I was slightly biased by my editor.

I use Emacs in Web-mode. The keyboard shortcuts allow me to navigate and edit HTML quickly.

But the more I use modern web technologies, the more I realize the days of long HTML files seem long gone. Modern web development is based on Components which have much shorter HTML code.

Using Gatsby forced me to figure out how to set up Emacs to handle JSX, and it was easy, I can still use Web-mode, I also installed Prettier JS to format the code.

One thing that blew my mind was realizing what Javascript ES6 had to do in order to integrate HTML and CSS in a way that makes sense programmatically. What I realized is that HTML tags became another syntax for functions. And tagged string literals are really a way to write CSS as functions.

Conceptually, this realization made it really easy for me to adopt HTML and CSS in Javascript.

And so, armed with my code editor, yarn, and node, I began to give Gatsby an earnest try.

In the past, I gravitated toward CSS frameworks with little styling so I can create my own styles. That is why I would often use Zurb Foundation instead of bootstrap in my projects

However, when I need to develop quickly without needing full creative freedom with design, I use Bootstrap or Materialize.

While learning Gatsby my inclination was toward a minimalist framework, and Tailwind CSS fit the bill with its "utility first" approach.

I played around with Tailwind for about half a day, and while I got really excited about the utility-first approach, in the end, I kept wondering what the best practices are for creating components using Tailwind. Combine that with how verbose my code was becoming and having to constantly reference the utility classes, I decided to take a break from Tailwind for some time.

Right now I want to find a way to create the perfect landing page in terms of design and performance. But I also want to start generating some landing pages quickly.

I will come back to Tailwind perhaps if I find a library of React components that use Tailwind or if I end up designing and building my own. But that's another animal.

So I decided to use my trusty Themeforest to look for websites built with React, and lo and behold, I not only find templates built with Gatsby but also that use Styled Components.

I look at the demos and run through Pagespeed insights. They score in the 50s on mobile. What! Oh, images are not optimized. Easy fix. But I'll have to do that on localhost.

So I looked for a free version I could try and found Startup Landing by RedQ

Download! yarn. yarn build, yarn serve. Incognito. Lighthouse. Test.

Off the bat, I’m impressed with what I see in the Network tab.

The app bundle is 35KB. The commons bundle is 57KB. Compare that to my Nuxt website which has an app bundle of 115KB and a commons bundle of 57KB. Not bad.

Now I quickly replace all images with webp versions just for testing and to make Lighthouse happy

However, I'm disappointed when I see the mobile Pagespeed insights score is 59. The Last Contentful Paint (LCP) is reporting 4.8s.

What? OK, the largest element was the image, so I removed it to make the Text Block the biggest element.

The LCP is now 3.2s  score improved to 79

I looked at the code, and it is well organized. The code is simple. I looked at the Home Page component, removed all the child components except for the banner

Still not getting a good score.

But why? I tried another Gatsby Starter called Cara and it scores 98, I know it is possible.

I decide to take a look at the performance audit generated by Lighthouse. But first I have to disable "Simulated Throttling."

But this time, LCP is 1.3s, and Time Blocking is 1800ms. So I look at the Main Thread and find several tasks related to Javascript that take longer than 50ms (one taking 1.2s).

It is at this point that I ask myself, why is this JavaScript necessary?

I'm sure I can get this to work like the Cara Gatsby Starter, but now I'm curious. Does a simple landing page even need JavaScript (aside from analytics)?

So, OK, I'll put Gatsby aside for a little bit. I think it is a great framework for making Single Page Applications (SPAs). But right now I want to make the perfect landing page.

In Part 3, I'll be exploring some Ultra minimalist JavaScript frameworks like Tropical, and trying to get rid of JavaScript as much as possible.

One last thing I’d like to briefly mention is my experience testing Nuxt and Gatsby with Lighthouse and Pagespeed insights.

There are field and lab tests. Lighthouse and Pagespeed give significantly different results every time you run a test without changing the code. Sometimes the culprit is LCP, other times is Total Blocking Time, even thought, like I said, the code has not changed. The performance tab in Chrome shows different measurements than Lighthouse due to “Simulated Throttling.” Results on localhost are different than testing at the hosting (i.e Netlify) because of HTTPS/2 and CDN.

WebPageTest actually gives straight A’s for all the tests I’ve done related to finding the perfect landing page.

Basically, testing is a little more complicated than running some Lighthouse tests.

I don’t yet have a good workflow for testing website performance. For now I’ll stick to testing with Chrome Dev Tools Lighthouse with default settings (“Simulated Throttling” enabled), then using PageSpeed Insights for testing once I upload to Netlify.