lego, not yet another Static Site Generator
Sivasubramanyam A
Posted on October 5, 2019
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 taggedJavaScript
. - 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!
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
October 26, 2024