lego, not yet another Static Site Generator

astronomersiva

Sivasubramanyam A

Posted on October 5, 2019

lego, not yet another Static Site Generator

I have been working for over a year on lego, a static site generator written in JavaScript. When I decided to rewrite my site, I had a wide variety of SSGs to choose from. I eventually narrowed down my choices to the following:

  • Gatsby - I really liked how optimised the output was with Gatsby. The only issue I had with Gatsby was the slow build timings.
  • Hugo - I loved Hugo for its speed. However, the templating language was frankly too disappointing.
  • Jekyll - This was fast enough for my site's size and the templating language, Liquid, was pretty similar to Jinja2. However, doing Gatsby like optimisations was challenging.

I had way too much free time on my hands so I did what every bored developer does. Write my own framework. In this case, I decided to write my own static site generator that emulates the good parts of these three frameworks.

I had a few requirements out of this and decided to try building it for a week or so and see how feasible this was.

  • Support Liquid(recently added Nunjucks support).
  • Support Markdown posts, data in YAML(later extended to JS and JSON).
  • Transpile and uglify JS with terser, use PostCSS for CSS(both use browserslist to determine targets).
  • Revision assets like JS, CSS and images.
  • Optimise images.
  • Extract and inline critical styles with critical for all pages.
  • Minify HTML of all pages.
  • Generate a tag-wise listing of posts. For example, site/tags/javascript should list all pages tagged JavaScript.
  • Live Reload during development.

Surprisingly it turned out pretty well. There were still a few rough edges but I quickly ported over my site in the hopes that I could fix them.

This is when the fun began.

lego was taking about 5-6 seconds to start up. While this was not that bad compared to Gatsby, I wanted to squeeze out as much performance out of it as I could. The whole purpose of this project was to learn something and have fun in the process so I decided to profile lego. A few interesting things stood out.

  • Just requiring PostCSS plugins was taking a second or two.
  • Some code paths were running more often than necessary.

After fixing these, it came down to about 2-4 seconds.

This is when I started looking into caching. While coming up with a technique for this was challenging, the actual implementation was rather trivial. After implementing caching, I felt satisfied with this whole endeavour of writing my own SSG. I now had a fast, performant SSG that generated an optimised site.

Right now, lego starts up a development server for my own site in under 600ms. Rebuilds take under a couple hundred milliseconds. Production builds take about 20 seconds!

I wrote a benchmark to test all this. When Liquid templates are used, lego is about 1.5x faster than Jekyll and when Nunjuck templates are used, lego is a cool 8.7x faster than Jekyll.

I then added a few more things like RSS Feed generation and sitemap generation based on my own needs. While lego supports auto-generating responsive images, I think it's a little less robust and I will start paying attention to it in the coming days.

If you are feeling adventurous and want to try this out,

  • Run npm i -g @astronomersiva/lego.

  • Generate a site using lego g my-awesome-site. This will generate a dummy site.

  • Run lego s to start the server.

You can also checkout the code on GitHub.

Have a great weekend folks!

💖 💪 🙅 🚩
astronomersiva
Sivasubramanyam A

Posted on October 5, 2019

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related