Publisync
RSS
Performance

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.

Aarav Mehta

Writes about performance engineering, Postgres and Go. Builds publishing systems that stay fast.

All posts by Aarav →