I’ve written previously about the performance outcomes of transitioning cloudcannon.com to Eleventy, which include perfect Lighthouse scores and excellent Core Web Vitals scores. We’re now several weeks into the flow of building our site pages, as well as drafting, editing, and publishing blog posts on Eleventy with CloudCannon as our CMS, and it’s been, as we expected, a joy to work with. But I’ve also wanted to dig a little deeper into each of the tools we used to achieve our performance gains, and to share how we configured these tools. So let’s get started, shall we?
One of the easiest tools to include in our new stack was Jampack from <div>RIOTS, who you may know as the developers of Backlight; the Figma plugins story.to.design, html.to.design, and code.to.design; and the online IDEs WebComponents.dev, LWC.studio, and Components.studio. Altogether, these tools are used by hundreds of thousands of developers and designers — and for a reasonably small core team, <div>RIOTS punches well above their weight.
In brief, Jampack is a post-processing tool that takes the output of any static site generator and optimizes it for user experience and Core Web Vitals scores. Jampack is one of several open-source tools that the <div>RIOTS team have created. It was released at the end of January 2023, and as soon as we heard about it, we immediately started testing it out.
I’ll go into more detail below, but in brief, I would recommend Jampack to any CloudCannon user, or indeed anyone with a static site.
Why the blanket endorsement? Primarily because Jampack is SSG-agnostic. While we use Eleventy to build cloudcannon.com, everyone who works at CloudCannon uses a range of static site generators to build our personal sites, and Jampack works with all of them. (Even, of course, those built without an SSG — because all Jampack requires is a folder containing an output static site.)
Quite a lot, really! Here’s a quick summary of the major steps Jampack takes when it’s run:
Jampack compresses images with the high-performance
sharp processing module;
PNG images are converted to
WebP. Jampack also creates responsive images for smaller devices, and assigns image dimensions to avoid any CLS issues.
Jampack introduced a new
<the-fold></the-fold> mark that you can add to your HTML to mark where a page’s fold should be. Based on this mark, Jampack prioritizes images above the fold and turns them into progressive JPEGs for a better user experience. If images above the fold are smaller than 1500 bytes, Jampack embeds the image into html using data URLs.
Below the fold, Jampack lazy-loads all images and iframes.
In its second and final pass, Jampack compresses all untouched assets, keeping the same name and same file format for each:
|Elements of both |
Check out the Jampack docs for more detail, and also the available CLI options.
To add Jampack to cloudcannon.com, we simply added a single line to our postbuild file, which runs on our production site. (While we could run Jampack on our staging branch, or on every single branch we make, we’re privileging the production branch here, and in the process shaving off a very small amount of post-build time when we’re working on new site content earlier on in our publishing workflow.)
Because Jampack optimizes above the fold, we’ve also built a specific Bookshop component to indicate where the fold should be. If you use Bookshop to manage your components and would like to do the same for your site, here’s that component’s data file:
Indicates where the page fold is.
Everything below this point will be lazy loaded.
This component, when added to a page by editors using CloudCannon’s Visual Editor, simply inserts the following between other page components:
It’s a really simple step, but it gives me and our team of editors a lot of control: we’re able to precisely determine which parts of a page should be more heavily optimized, and which should be lazy-loaded.
As you can see above, we generally set the fold at the end of the first ‘container’ component on each page. (We've set our Bookshop components to be shown or hidden, depending on mobile, tablet, or desktop breakpoints; to make sure that Jampack optimizes above the fold for all device types, we set the fold under all device-specific versions of that top component.)
Jampack fits into a workflow we refer to internally as ‘SSG chaining’ — like our open-source search tool Pagefind, and our translation management tool Rosey. The general idea of SSG chaining, as we use the term, is that static sites can (and should) stay simple — and static site generators shouldn’t have to ship and build every single possible feature or optimization strategy. Instead, users can first build their sites using any SSG they like, and then ‘chain’ a series of post-build tools on the static output.
Rather than building an optimizer or a search plugin for a dozen different SSGs, tools like Jampack are able to share the benefits they offer across the whole static site ecosystem. And when a newer, shinier SSG comes along, there’s no question that these SSG-chaining tools will still work on them: because there’s not the sense of lock-in that can come with plugins we depend upon, developers are freer to shift between static site generators, while still using their preferred post-build tools.
Though I think we’re seeing some major development tools and frameworks feature-creep towards full meta-framework, jack-of-all-trades, gotta-catch-them-all status, Jampack reminds us that it’s possible to escape that particular rat race. Or at least to sidestep it, and give every developer the same Core Web Vitals advantages, regardless of the tools they choose to build their static sites.
Give your content team full autonomy on your developer-approved tech stack with CloudCannon.
Jaimie McMahon · 16 May 2023
David Large · 27 Mar 2023
Jaimie McMahon · 3 Mar 2023