Server Components, One Year Later
For a long time I treated Core Web Vitals as something to worry about later. Then a small change to our Astro setup turned into a week of debugging, and "later" arrived all at once.
When we finally measured, the numbers were worse than anyone guessed. Around 29% of the time spent on a typical change went into working around Core Web Vitals rather than building anything.
Some background
Most of the complexity was accidental. Over the years we'd layered three different approaches to Core Web Vitals on top of each other, and each one made sense at the time.
We had good intentions. We even had a document describing how Core Web Vitals should work. The trouble was that the document and the code had quietly gone their separate ways.
Trying something different
Rather than a big-bang rewrite, we migrated one module at a time over about 8 weeks, keeping both paths alive behind a flag.
The core of it looks like this:
.card-list {
container-type: inline-size;
}
@container (min-width: 36rem) {
.card {
display: grid;
grid-template-columns: 12rem 1fr;
gap: 1.5rem;
}
}
Nothing about this is clever, and that's the point. Anyone on the team can read it in a minute and know exactly what it does.
A few things that helped along the way:
- Keep the old path around until the new one has survived a real incident.
- Make the default the safe choice, not just the documented one.
- Write the migration guide before writing the migration.
- Pair on the first few changes so the knowledge doesn't live in one head.
Caveats
We still haven't solved server-side rendering. That's a post for another day, and honestly, I'm not sure we'll get it right the first time either.
The biggest cost was social, not technical. Changing how people think about Core Web Vitals takes much longer than changing the code.
Takeaways
That's it for now. Next time I'll dig into accessibility, which turned out to be closely related.