Skip to content

In-place XML tree mutation for Jekyll productivity

dev

I wrote a reveal.js plugin for Jekyll so that I can make nice slides (especially for my ANUcourses). Recently, though, I’ve been touching up the COMP1720 slides for 2019 and it’s getting really slow to build the website.

I turned to Jekyll’s built-in profiling command to see where the problem is. Here’s the output of jekyll build --profile on this website, which (currently) builds in 7.2 seconds on my machine.

FilenameCountBytesTime
_layouts/reveal.html9104.60K4.102
_layouts/default.html81729.15K0.809
_includes/head.html90266.90K0.702
research.md116.40K0.196
_includes/hljs.html9029.44K0.192
_includes/slides/background-image.html931.94K0.154
_layouts/paginated.html2170.29K0.078
_talks/u3a-world-since-google.md114.49K0.058
_includes/header.html8185.88K0.042
_talks/ltc-stem-camp.md113.38K0.040
feed.xml1105.55K0.038
…more inconsequential stuff follows…

Clearly, the reveal.html layout is the problem, taking 4.1s (more than half the total build time). I suspect that this is because my reveal plugin does a bunch of copying of (Nokogiri) XML nodes, because I wasn’t worrying about performance when I wrote it.

Re-parent all the nodes!

Looking at the Nokogiri API and the revealify.rb plugin code, there are a bunch of places where instead of duplicating & copying nodes, I can just re-parent them into the right places. I’m a big immutability fan usually, which is why I built the plugin based on copying originally, but with a bit of careful re-parenting the revealify.rb plugin now looks like this (see the linked post above to see what it looked like before).

And the result? Total build time is down to 2.8 seconds. Admittedly that was because it was really inefficient before, but I’ll take a 2.5x speedup anyday 😊. Here’s the relevant profiler output with the updated plugin:

FilenameCountBytesTime
_layouts/default.html82741.77K0.873
_includes/head.html91269.82K0.780
research.md116.40K0.198
_layouts/reveal.html9105.65K0.182
_includes/hljs.html9129.77K0.172
_includes/slides/background-image.html931.94K0.151
_layouts/paginated.html2170.55K0.101
_talks/u3a-world-since-google.md114.50K0.058
_includes/header.html8286.94K0.045
_talks/ltc-stem-camp.md113.39K0.041
feed.xml1112.62K0.029
…more inconsequential stuff follows…

Wow, the reveal.html layout has gone from 4.1s to 0.2s, a 20x speedup!

So I guess the moral of the story is that profiling is important, and that avoiding copies and writing filthy mutable code is helpful as long as you’re careful.

Now that I’ve done procrastinating with this stuff, I can get back to writing my slides for the upcoming semester.