Your blog does not need 1.2 MB of JavaScript
Most publishing stacks ship a framework, a hydration pass and a font stack to render what is, functionally, a text document. Here is what happens when you delete all three.
The average WordPress site ships roughly 2 MB before the first paragraph is readable. A modern React blog is not much better: a router, a runtime, a component library, three font files and a hydration pass — all to render text that was final the moment the request arrived.
I rebuilt this one on the opposite principle: the server renders the document once, and the browser does almost nothing.
What the browser actually receives
- One HTML document, CSS inlined in a
<style>block, JSON-LD inlined in<script type="application/ld+json">. - One 2 KB script at the end of the body: theme toggle, a like button, a markdown toolbar for the admin editor.
- Zero webfonts. Zero third-party requests. Zero framework runtime.
Total transfer for a post page, compressed: under 30 KB. Not “under 100 KB after weasel words” — the whole document, style and script budget lands at roughly a quarter of one hero image from a typical CMS.
Why hydration is the wrong default for text
Hydration exists to make a server-rendered tree interactive. If a page has no interactive tree, hydration is pure cost: it parses, executes, and reconciles a DOM that was already correct. The measurable damage is not only bytes — it is the main thread being busy during the exact window when a reader tries to scroll.
Interaction to Next Paint punishes that. A text article with a comment form needs, at most, a few hundred lines of hand-written script.
Delete the framework, and the performance work stops being a sequence of defensive hacks. It becomes the architecture.
What you give up, and how to get it back
You give up: client-side routing, component ecosystems, a build pipeline with HMR.
You get back: a deploy that is a single binary, a page that renders in single-digit milliseconds server-side, and a stack you can still understand in two years. For a busy index or search page you can add a tiny fetch call. For an editor, you can put the expensive UI behind /admin where a 200 KB page costs nobody anything.
That is the trade this platform makes. Text is served as text. The admin console — where heavy UI actually earns its bytes — loads its own CSS, and only editors ever pay for it.
The budget as a build gate
A performance budget that is not enforced is a wish. The page-weight script runs on every release and fails the build if the document exceeds the limit. If you want to know whether a change was free, you do not guess — you run the check and read the number.
./scripts/pageweight.sh http://localhost:8100/why-rendering-once-wins
# document 24.8 KB gzip · css 3.4 KB · js 0.9 KB · total 29.1 KB ✓ under 100 KB
The constraint is the feature. Everything else follows from refusing to break it.