Training Under the Shell: A Performance Budget That Actually Hurts
Master Roshi made Goku carry a turtle shell before he could carry anything else. My performance budget works the same way.

Before Goku threw a single punch that mattered, he spent months carrying a shell on his back that was heavier than he was. He didn’t get to take it off to make training easier. That was the entire point — you build strength against a constraint you can’t negotiate with, and the shell comes off the day you’ve actually earned it, not the day it’s inconvenient.
My blog’s performance budget is that shell.
The budget, in numbers
Every page on this site has to clear these on a throttled connection, checked on every build:
- Total page weight under 150kb, images included
- Zero render-blocking requests outside the one font file the page actually uses
- Largest Contentful Paint under 1.2s on a simulated slow 4G connection
- No client-side JavaScript unless a component earns it with interactivity a static tag can’t provide
None of these numbers are sacred. What’s sacred is that they’re checked automatically and I don’t get to argue with the number in the moment I’m tempted to add a carousel.
// astro.config.ts
export default defineConfig({
build: {
assets: '_assets',
},
image: {
// Every image ships as both AVIF and a JPEG fallback,
// generated at build time — no runtime image service to pay for or trust.
service: {
entrypoint: 'astro/assets/services/sharp',
},
},
})
That config isn’t exciting. It’s not supposed to be. The excitement was supposed to happen at design time, when I decided every image on this site goes through astro:assets and gets real widths and sizes instead of a single 4000px source getting squeezed down by the browser.
What the shell actually catches
The budget doesn’t stop bad ideas. It stops good ideas that are bad for this site. A syntax-highlighting library that ships its own theme engine. A view-transitions polyfill I don’t need because Astro already does most of this at the HTML level. An analytics snippet that pulls in a 40kb client bundle to tell me twelve people read a post about turtle shells.
The weight isn’t the punishment. Carrying weight you didn’t choose is the punishment. Carrying weight you chose, on purpose, to get stronger — that’s training.
Every one of those ideas is legitimate somewhere. None of them are legitimate on a static blog whose entire job is to put my sentences in front of your eyes as fast as possible. The budget is what lets me say no to a good idea without relitigating the decision every time.
The part that actually hurt
The honest version of this story is that I broke the budget twice building this exact post. Once because I was going to embed a code sandbox instead of a static code block — reverted, because a <pre> tag doesn’t need a runtime. Once because I wanted a table of contents that highlighted the active section on scroll — reverted again, because that’s a six-line CSS :target trick away from working with zero JavaScript.
The shell doesn’t get lighter because I have a good reason. That’s what makes it training instead of decoration.