Published

Inexactly benchmarking Eleventy vs Astro build times

The Eames Institute team is checking out some frameworks and static site generators for a project, and I wanted to see how Eleventy and Astro compare in terms of build time.

Zach Leatherman’s 2022 article “Which generator builds Markdown the fastest?” is probably the most thorough resource I’ve come across along these lines, and I’d recommend checking that out if you want to do some serious comparisons.

But I was curious about a “real world” test in 2024, so I decided to do some inexact benchmarking using a Markdown export of this blog. A caveat up front: I’m much more familiar with Eleventy than I am with Astro, which will likely be apparent when I get to the incremental build tests later in this post.

For Eleventy I used eleventy-netlify-boilerplate with zero modifications, and for Astro I used the blog template as described in their docs with some small modifications along the lines of this wordpress-to-astro repo to get categories and tags working. I didn’t want to use wordpress-to-astro directly since it was last updated two years ago, but it is a good reference point.

My blog has 770 posts which were exported to 770 Markdown files. With a paginated feed, categories, and tags, the total number of built pages is around 2550.*

Based on an average taken from 10 builds, Astro took 10.07 seconds and Eleventy took 4.29 seconds to build.

Incremental builds can speed things up significantly since the only built content is that which is relevant to the modified files.

Eleventy has supported incremental builds since December 2022 (I believe!), but it doesn’t yet support it on a CI server. There is an open issue for it which looks like it has traction.

To test incremental builds, I added and removed the same single tag on the same post 10 times.** Based on an average taken from 10 incremental builds, Eleventy took 2.17 seconds skipping 777 files. I would have expected it to skip more, but this might have to do with not being able to incrementally build paginated data.

I wanted to test the same content change in Astro… but it isn’t clear to me that there is an apples-to-apples comparison. Astro introduced an experimental Incremental Content Caching feature in v4.0 (not sure if this is supported on CI servers). When I added experimental.contentCollectionCache to the config, there was no difference between basic build times when I made a content change. I’m not sure if this is because having all of my content in Markdown makes the caching a mute point, or if it’s something else. If anyone has further context on how best to test Incremental Content Caching in Astro, would love to know.

For what it’s worth, running astro dev is extremely quick, just 125ms before it’s ready.

I’d be curious to do a similar benchmark using WordPress’s REST API but am not sure I’ll have the time… Will update here if I do.


* I give a rough number because the Eleventy boilerplate and Astro template generate a few additional pages, but the page total difference is in the single digits so I didn’t waste time evening them up perfectly.

** For my own future reference in case I do further tests: Add and remove the tag hello from this post.

Published

What to do if Command + R won’t reload your VSCode window

So CommandR hasn’t been reloading my VSCode window. But the “Reload window” command in the palette (ShiftCommandP to open palette) shows that it should work. Charles told me how to fix it!

To sort it out, click the cog icon next to the “Reload window” command in the palette to open the Keyboard Shortcuts settings for that command. Then under the “When” column, right-click isDevelopment and select “Change when expression”. Delete the contents, then press enter. There should now be a dash under “When” to indicate that it’s empty. Close the Keyboard Shortcuts file, then try reloading a window by typing CommandR and it should work.

Published

My custom bash prompt

This is my custom bash prompt, as defined in my profile (~/.bash_profile). It includes a custom character for the prompt, the path, and the Git branch name (if any). The whole thing is colorful to make it a bit easier to identify the prompt in a sea of characters.

When I’m working on this WordPress theme for example, it looks sort of like this (RSS readers, you’ll miss the colors):

~/sites/commonplace-wp-theme (v0.1.5)

To generate something else, try messing around with the Bash $PS1 Generator.

If you want to try something like this, do not delete the rest of your profile. Just add this at the top.

# Get the Git branch
parse_git_branch() {
  git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ (\1)/'
}

# Custom bash prompt
# Includes custom character for the prompt, the path, and Git branch name. With colors!
# Source: kirsle.net/wizards/ps1.html
export PS1="\n\[$(tput bold)\]\[$(tput setaf 5)\]➜ \[$(tput setaf 6)\]\w\[$(tput setaf 3)\]\$(parse_git_branch) \[$(tput sgr0)\]"

Note: I got this from someone else at some point… I’m trying to figure out who but haven’t gotten to the bottom of it.

Published

Fluid type sizes and spacing

I’ve been using a fluid type and spacing system on the most recent builds I’ve completed. Here’s why I use it, and how I approach it. I mainly use SCSS (a Sass syntax), but it’s also very do-able with plain CSS.

Screencast of Gort Scott’s homepage, resizing it in Chrome’s inspector

The example above demonstrates the result on gortscott.com, resizing the window from about 2300px down to about 640px and back again. The type and spacing across the page begins scaling down when the window is 2095px wide and stops shrinking at 1047px wide. At that point the text begins to reflow as the CSS Grid layout continues to shrink. Eventually at 703px wide the layout shifts, and again at 543px wide.

Read more

Published

CSS blend modes: beware the stacking context

I’m working on a site with a complex entanglement of blend modes, SVG backgrounds, gradient backgrounds, positioning, and transitions. I’ve run in to a bunch of issues with mix-blend-mode not working as expected, and it almost always has to do with an inappropriate stacking context.

For posterity, this StackOverflow answer is a really good run-down of CSS combos that create new stacking contexts.

Now to see what I can do about browsers rendering color profiles slightly differently… 💀


Edit: UGHHHHHH it’s different in different browsers. Check out this CodePen in Chrome and Firefox vs Safari. This is why we can’t have nice things.


Edit 2: See the answer to the cross-browser problem from the previous CodePen, via Gregory Cadars (view thread). So Safari is actually behaving correctly, but it’s still a stacking context issue.

To recap: I’m trying to display a “fixed” gradient background with content that scrolls over the top of it. Within this content, only the images have mix-blend-mode: overlay. In the original CodePen, I’m achieving this via a fixed position, 100% width + 100% height element with a linear gradient. This is within the same wrapper as the content.

My example is working in Chrome and Firefox. In Safari, it is effectively as if the blend mode hasn’t been applied. Though I’m not sure why the difference between browsers, it does make sense that a fixed position element would still create a new stacking context regardless of its parent.

In Gregory’s example, he’s removed the fixed position element with the gradient and instead applied the gradient background to the wrapper, as well as background-attachment: fixed via the background shorthand. This achieves the exact same effect, without stacking context issues.

The only thing that gives me pause is performance… I remember running in to some issues when I considered using background-attachment: fixed for Elizabeth Peyton’s Eternal Return. I can’t remember what it was exactly but it had to do with repainting on every scroll event (so, a lot!). I think that this article may give some context, but I’ll have to dig in to it further.

Related: See this CSS gradients resampling tool by Rutherford Craze for smoother gradients, shared by Gregory in the thread.

Twitter is a crappy place a lot of the time, but I love it for things like this.

Published

Gemma’s site in AIGA Eye On Design

Read “There’s More Than One Way to Share Your Design Work: Four fresh takes on the portfolio” on AIGA Eye On Design.

They spoke to Carly Ayres, Prem Krishnamurthy, David Reinfurt, and Gemma Copeland about their approaches to an online portfolio / website. Gemma spoke a bit about how we designed and built her site together, it was a lot of fun. See her site gemmacope.land, or take a look at the GitHub repo. BIG thanks to Howard Melnyczuk for fixing a bug I totally missed. 🤦🏻‍♀️ 🙏

Published

Sass + Eleventy, remember to opt out of using .gitignore

I’m working on an Eleventy site at the moment, the first Eleventy site I’ve done that’s been complex enough CSS-wise to warrant using Sass. I’ve turned to Phil Hawksworth’s Sass + Eleventy technique for the job. It’s a great, simple way of using Sass with Eleventy with a little bit of preprocessing courtesy of Gulp.

Hit a wall at one point though, it was smooth sailing and then my CSS updates just stopped working.

Turns out I had added /_includes/main.css (the compiled styles) to my .gitignore file since I prefer not to commit compiled files, but I forgot that Eleventy uses the .gitignore file + the .eleventyignore file to decide what not to compile. So Eleventy was just ignoring it. 🤦🏻‍♀️

I did this .gitignore change as an end-of-day commit, tidying things up before closing my laptop. When I picked the project back up days later, it took me longer than I’d like to admit to figure out what was going on!

To sort it, I just had to opt out of using .gitignore by adding eleventyConfig.setUseGitIgnore(false); to the .eleventy.js config file, and then adding the necessary files listed in .gitignore to .eleventyignore. Then I re-ran gulp watch & npx eleventy --serve, and all was well.

Separate but related to static site generators: Check out Astro. Would be curious to see a detailed comparison of Eleventy vs Astro since Eleventy is currently top-of-the-list for me in terms of static site generators.

Published

Two articles on SPA or SPA-like sites vs alternatives

I missed these two articles by Tom MacWright from last year.

Second-guessing the modern web, 10 May 2020
If not SPAs, What?, 28 October 2020

In both, he outlines few upsides and downsides about the single page app (SPA) approach to websites and has a few points that I have really struggled to articulate in the past.

From “Second-guessing”:

There is a swath of use cases which would be hard without React and which aren’t complicated enough to push beyond React’s limits. But there are also a lot of problems for which I can’t see any concrete benefit to using React. Those are things like blogs, shopping-cart-websites, mostly-CRUD-and-forms-websites. For these things, all of the fancy optimizations are trying to get you closer to the performance you would’ve gotten if you just hadn’t used so much technology.

I’ve dabbled with React and Vue in small side projects and experiments. But the point above is the big reason I’ve never taken the time to sit down and learn either of them properly. For almost every client site I’ve ever done, it just didn’t make sense to make it an SPA.

And I’m not 100% sure, but I think this might contribute to longevity. Some of my clients are still working with the same sites I built for them nearly 10 years ago, a few with just minor security-related updates in the meantime and no other maintenance strictly required. That’s not to say that those sites couldn’t use a “lick of paint” to bring them in to the 2020s; the point is that they work. And for organizations working on really tight budgets, or budgets that fluctuate wildly due to public funding, stability is really important. They can’t afford a developer on retainer to keep things running smoothly.

But of course the SPA vibe is pretty attractive, particularly for cultural orgs. MacWright has some decent alternatives suggested in “If not SPAs” including Turbolinks, Barba.js, and instant.page. Will also mention MoOx/pjax since I’ve used it before for page transitions with very good results, but probably won’t use it in the future as it hasn’t been updated in a while.

And again, there’s the rub. The more non-native scripts, plugins, etc I use in a project, the more likely that it’s going to be a major headache (and thus major time/money for the client) for me to change things down the line if or when that bit of tech is no longer supported or has changed significantly.

So it’s not even so much about being wary of React or Vue, it’s about not making assumptions, being cautious and cognizant of future needs or restrictions when proposing a tech stack. Any tech stack you choose will ultimately become a ball-and-chain, not just those based on JavaScript frameworks. It’s just that the ball can sometimes be heavier than it needed to be, and you can anticipate that with a little foresight.