The Progress Bar That Goes Backwards: A Jetpack Boost Source Code Archaeology

A woman engineer watches a progress bar on her monitor that climbs and drops in a jagged sawtooth pattern, with a magnifying glass hovering over source code behind her

You click “Regenerate Critical CSS.” The progress bar crawls forward: 20%, 30%, 40%. Then it drops to 20%. Climbs back to 50%. Drops to 35%. Eventually it hits 100%, and you exhale. Then it starts over from 0%.

This is not a fever dream. This is Jetpack Boost’s Critical CSS generator. Jetpack Boost is Automattic’s free WordPress performance plugin; its headline feature is generating and inlining Critical CSS to speed up page rendering. The behavior above is partially intentional, partially buggy, and entirely educational if you care about writing code comments that don’t lie.

I went spelunking through the source code to understand what’s actually happening. What I found is a case study in UX tradeoffs, concurrency bugs, and one code comment so perfectly ironic it deserves its own blog post.

Quick Context: What Critical CSS Does

Critical CSS is the minimal subset of your site’s stylesheets needed to render above-the-fold content. You inline it in the <head> so the browser can paint the page without waiting for external CSS files to download. Everything else loads asynchronously.

Jetpack Boost’s free tier generates this CSS in your browser. When you click “Regenerate,” the React admin UI launches hidden iframes, loads representative pages from your site, and extracts the CSS rules that affect visible elements. The server coordinates the process; the browser does the actual work.

The Provider System

Boost doesn’t generate one blob of CSS for your entire site. It generates separate CSS for each “provider” (page type):

For each provider, the generator loads the page in three viewport sizes (phone at 414×896, tablet at 1200×800, desktop at 1920×1080) and extracts the above-fold CSS for each. The progress bar reflects completion across all providers.

The progress formula is straightforward:

With 5 providers, each one contributes 20% when fully done, plus a fractional amount while in progress. Simple enough. So why does the bar go backwards?

The Comment That Lies

Here is the actual source code from generate-critical-css.ts, inside the loop that iterates through providers. This runs immediately after each provider finishes:

Read that comment again. “To prevent progress bar jank.”

Here’s what actually happens at each provider boundary. Suppose we have 5 providers and provider #3 just finished:

The bar jumps from 80% to 60% because the code zeroes out the sub-progress after the completed provider count has incremented but before the next provider has made any progress. This happens at every provider boundary. With 5 providers, you see 4 backwards jumps.

The comment says this “prevents jank.” The users see jank. The comment is describing the developer’s intention, not the code’s behavior. These are not the same thing, and confusing them is one of the most common commenting mistakes in software.

What the Developer Was Actually Trying to Prevent

To be fair, there is a brief moment (step 2 above) where the bar shows 80% when arguably only 60% of the work is done (3 of 5 providers complete, with no sub-progress on the 4th). The developer saw this momentary overshoot and decided it was worse than a backwards jump.

They were wrong, but the reasoning was coherent. The problem is that the comment doesn’t explain the tradeoff. A better comment would be:

That comment is honest. It tells you what the code does, why, and what you’ll observe. The original comment tells you what the developer wished the code did.

The 100%-Then-Restart Bug

The backwards progress is annoying but cosmetic. The restart-from-zero problem is a real bug, and it has multiple causes.

Cause 1: The Double-Click Race Condition

GitHub Issue #31543 documents this precisely. If you click the Regenerate button twice before the server responds, two generators start running in parallel. Both are writing to the same React state via setProviderProgress. The progress bar bounces between the two generators’ positions like a tennis ball.

The fix was to optimistically set the state to pending after the first click, which should disable the button. But the optimistic state uses an empty provider list:

An empty provider list means calculateCriticalCssProgress tries to divide by zero. The button may or may not disable in time, depending on connection speed. The fix has a bug.

Cause 2: The Auto-Regenerate Trigger

The React component watches for a not_generated state:

If anything resets the state to not_generated during generation (a theme switch, for instance), the 2-second polling loop detects it and fires a brand new generation cycle. Progress drops to 0% with no warning or explanation.

Cause 3: The Effect Dependency Trap

The React effect that launches the generator depends on cssState.providers.length:

If the provider count changes mid-generation (someone adds a cornerstone page while CSS is generating), the effect re-fires and can spawn a second generator alongside the first. Same tennis ball problem as the double-click bug.

The Freemium Nag You Can Ignore

Every time you publish a post, Jetpack Boost sets a suggest_regenerate flag and increments a “problems” counter on the dashboard. The message implies your Critical CSS is stale and needs regenerating.

Here’s what actually happens when you publish a post:

Your CSS is fine. The homepage layout is templated; post #347 renders in the same CSS structure as post #346. The only event that actually deletes your CSS is a theme switch (which makes sense, since a theme change genuinely invalidates all your CSS rules).

The paid tier (Cloud CSS) auto-regenerates seamlessly via Automattic’s servers. The free tier makes you do it manually in your browser while watching a progress bar that goes backwards. Draw your own conclusions about the incentive structure.

For the record, I checked the source. Here’s the complete list of what each event actually does:

Notice that “post published” and “theme switch” produce the same nag but wildly different actual behavior. The UI doesn’t distinguish between “your CSS is genuinely invalid” and “something changed and we thought you’d like to know.”

Lessons for the Rest of Us

This isn’t a “Jetpack is bad” post. Jetpack Boost is a free tool that provides real value, and the Critical CSS feature works correctly once it finishes generating. The generated CSS is fine. The UX around generation is where the wheels come off.

But the code comment is the part I can’t stop thinking about. “Reset local progress whenever a provider is finished to prevent progress bar jank” is a comment that has been read by every developer who has touched this code path, and none of them thought to check whether it was true.

Here’s the principle: A comment that describes what you intended the code to do, rather than what the code observably does, is worse than no comment at all. No comment leaves the reader uncertain. A wrong comment leaves the reader confident and wrong.

A few guidelines for comments that age well:

  • Describe the tradeoff, not just the intent. “Prevents X at the cost of Y” is more useful than “Prevents X.”
  • If your comment describes a user-visible behavior, verify it. Watch the actual UI. Click the actual button.
  • If the behavior has changed since the comment was written, update the comment. Stale comments are technical debt that compounds invisibly.
  • Comments should explain why, not what. The code already says what it does. The comment should say why that’s the right choice, including the alternatives that were considered and rejected.

The Known Issues

For anyone who wants to dig deeper, here are the confirmed GitHub issues in the Automattic/jetpack repository:

  • #31543 – Double-click spawns parallel generators; progress bounces (closed, partially fixed)
  • #22315 – Generation halts silently if module disabled during run (closed)
  • #39092 – UI stuck forever when a provider returns 404 (closed)
  • #40391 – Generation continues past critical provider failures (open)

Have you noticed the progress bar weirdness? Or do you just look away and wait for the notification? Let me know on Bluesky or LinkedIn.