Skip to content

Migrating from Jekyll to Eleventy

Blog Redesign - Part 4

Published by Vincent Pickering
on

Aplogies this post took so long to get out, I was struck with illness recently and it delayed getting this out. Feeling alot better now 😃

This post is part of a series where you can follow along as I redesign the blog and my IndieWeb Server.

News on the redesign has been quiet for a while as this was (probably) the hardest step in the process. I have a reasonable amount of customised content I wanted to get off the aging Jekyll platform on to Eleventy. I was already customising Jekyll with ruby gems to get my IndieWeb functionality working in a way I was comfortable with, so I took the decision that before I redesign the blog and update the Mastr Cntrl codebase; I wanted a stable platform to build from. In these situations it is very tempting to do the redesign at the same time you re-platform but inevitably this would make the project balloon in to an unacheviable goal for a weekend and evenings project. I needed to keep it acheiveble. One thing I am always concisous of in this project is that potentially there is a contract between actions on Mastr Cntrl and the blog and while (by design) the blog will not stop working if Mastr Cntrl does, I would like to keep everything working if I can and not overcomplicate things.

For the most part you shouldn’t be able to notice the difference. In the move to Eleventy a few things have changed. Most notably I removed the number of webmentions (likes, reposts, replies etc) from a post in my Lifestream. In the redesign I intend to remove these and the work increases complexity and build time so I simply removed them early.

My approach

In my day job I preach to “test by doing”. Determine the quickest path to get something working and test it for real, don’t be precious about the method, test first and learn. Then get precious about the quality of the final product once you are clear in the problem(s) you are solving and why you are solving them. Code is a means to an end, you can write the prettiest, most elegant code in the world, but if the system it underpins is complex or hard to comprehend. You code is worthless.

I took this approach with my initial pivot to Indieweb and the decision to create my IndieWeb server. The codebase is scrappy and written with a “minimum path to doing”. Over the last 2 years, I have been testing my approach. Thinking around what works and what doesn’t. I learned a lot that is going to inform the next phase. The replatform from Jekyll to Eleventy also took this approach. I recreated the site as close as I could allowing me the space to learn how Eleventy works and feel the edges of what it can do, ask some complicated questions and try to see if it was suitable. If it wasn’t, it was easy to stick with what I had. I didn’t commit to massive evolution of the blog to see it collapse in on itself and get depressed. The worst that could happen was that I had what I already had, the best that could happen, was a path to be better.

Where code is concerned I took the quickest approach to recreate the functionality. Not only did this help in my learning, but I knew I would be throwing away the code afterwards, so its easy to “just do it” and not worry about the quality only the outcomes. It’s a learning exercise to get where I want to be. I am a strong believer that you learn a lot quickly about a process by doing it and making all your mistakes and finding the gotchas. Then you can do it again better.

Eleventy

I am sure you have seen many of the blog posts, the tweets, and hype around Eleventy. Posts extolling how they moved their blog over in a few days and it was “super simple”. I am usually sceptical of these things, so before I decided to make the move I did some tests on my codebase and a lot of reading.

I have found Eleventy to be a good platform with some really neat ways of doing things and clever tricks, but I would be more measured in my enthusiasm than perhaps others. It is still in its infancy, if you have a complex question information is hard to find without tweeting the author or asking in Github issues, it’s nearly always possible to solve a question asked, but be aware if you are scared of code or don’t want to spend a while learning JavaScript it might be worth doing your own investigation before jumping in. While we are on this topic I should also mention the documentation, its a good start, but I really found both the website and its documentation quite confusing. Finding things is a little tricky until you are really familiar with the navigation on the site (it all looks quite similar, frequently I would be completely lost on the geography of the site) and most of the docs are in the format of introduction followed by a code dump example. It’s just kind-of assumed you know JavaScript well enough to follow the example and understand all the possible contexts you could use it. I was fine with this as I can muddle though, but you might not be. Read the docs before you dive in and decide if you can follow the examples and it makes sense enough. Especially if you are planning to do something slightly out of the normal.

On the plus side the author and the people in the eco-system are friendly and helpful which is a huge benefit and indicates Eleventy will be around for a good stretch. Personally I am quite excited for the platform, it feels a good fit for me and I am looking forward to where it goes.

Eleventy and Nunjucks

One of the things I really like about Eleventy and Nunjucks are the way they encourage you to move logic and processing in to the backend and out of your templates. Being able to create Nunjucks custom fillters and Eleventy collections are a neat and efficient way to keep code in the right place and inexpensive. I certainly noticed during this build process that template logic can get expensive fast. Slowing down the build time as the logic is parsed everytime the template is rendered. If you put that complex logic in a tempalte that gets parsed hundreds of times (like a post) its going to get slow quick. Moving the logic in a shared space and letting JavaScript do what it is best is pretty refreshing for a static site generator, often complexity in layouts is left almost entirely in the realm of the templating engine which isn’t a smart choice. This approach lends itself really well to an IndieWeb site that is using webmention data and not loading all the logic in the templating engine. Which leads me to…

Fixing a big gotcha

The point when I decided Jekyll was no longer meeting my needs came when build times were exceeding one minute. I knew exactly why this was, the logic required to parse through webmentions and output nice HTML code in liquid really put a strain on the engine. Commenting out the templates using webmentions would bring down the build time down from one minute to around ten seconds. It was a big pain, i tried various Ruby Gem solutions but nothing really worked well so I decided I had hit the limit of this platform.

During the migration to Eleventy I realised a little of this build time penalty was all my own making. Originally I had done what I thought to “keep things simple”. I created a folder in _data called webmentions and saved all the webmentions by the wm-id that comes from webmention.io. But this decision was a big mistake, it meant everytime I wanted to search for all replies to a post I would have to loop through all the data to find the matches. If I then wanted to find the likes, reposts etc I would loop through it again for each type. This would mean I would search and parse the webmentions on average 4-5 times per post, and everyime I added a new post it would magnify the problem further…Oops!

When I ported the code across from Jekyll to Eleventy I left it initially in Liquid and ran the code to see the build time. Eleventy clocked in at 41 seconds average. Between 10 - 15 seconds quicker than Jekyll for the same complex code. Good but I was sure I could do better.

The first step to reducing the time significantly was to separate the types of webmentions before appyling the logic. If I only had 3 reposts in total on the site, but I have hundreds of replies. I really don’t need to loop through the replies at all and certainly not for every post that doesn’t have any. I only care about the data that matters. In practice this was as simple as tweaking the folder structure to be _data/webmentions/replies or _data/webmentions/likes etc. Then creating a collection for each. I did this by globbing the folder, for the sake of getting this migration done. However you can reduce this time further, which I will implement during the redesign.

I back-ported the logic to my Jekyll site while it was live for a direct comparison (and to ease transition later). Jekyll came in at 27 seconds. Pretty great. Then I ran the same test in Eleventy and the build time came down to a shocking 5 seconds . I was impressed, but I know I can do better. Hopefully I can post some better results soon.

Why should we care about build time?

Technically, you don’t have to care if you don’t want to, but I find the exercise of building a static site that is running on a slowly growing set of data and it’s impact on build time quite a fascinating mini project that has good information for others in the same boat and answers questions like, is it really a good idea to do IndieWeb things at all with a static site or is it destined to collapse in on itself at some point? There is lots to learn in this space I feel.

What I learned

Things that feel right

  • The move to Eleventy, it’s faster and more flexible for my needs.
  • Keeping everything in one language, JavaScript, is much easier than context switching.

Things that need investigation

  • How I handle the logic for Webmentions, where it lives impacts things greatly.
  • Eleventy is really flexible and anything it can’t do, I can usually write a Nunjucks filter to solve.

Future Actions

  • With the migration done, I will be moving on to my IndieWeb server…

Likes