I checked my blog’s homepage recently:

$ curl -s -o /dev/null -w "Size: %{size_download} bytes | TTFB: %{time_starttransfer}s\n" nurazhar.com
Size: 5,255,649 bytes | TTFB: 0.718s

5.2 MB for a text blog.

Individual post pages were fine (~41 KB, ~0.29s). But the homepage was inlining the full body content of all 107 posts — including all D2 SVG diagrams, comparison tables, and code blocks.


The Root Cause

The index template was rendering {{post.body | safe}} for every post. For 107 posts with D2 diagrams, this ballooned to 5.2 MB.

The fix was trivial — show only metadata on the index:

Title + Description + Date + Tags

No body content. No SVGs. No code blocks.

Result:

Size: 168,695 bytes | TTFB: 0.187s

97% reduction. From 5.2 MB to 169 KB. TTFB dropped from 718ms to 187ms.


The Scale Question

My config has :num-index-posts 365. I initially worried this would be a bottleneck at scale. It’s not:

Format Size per post 107 posts 1,000 posts
Full body (old) ~49 KB avg 5.2 MB ~49 MB
Title + desc + tags (new) ~200 bytes 21 KB ~200 KB

Even at 1,000 posts, the index page is ~200 KB — smaller than a single post with one D2 diagram. The bottleneck was never the number of posts; it was inlining the content. Metadata scales linearly with negligible cost.


Other Fixes

Code Block Readability

The blog had syntax highlighting colors for dark mode only. Light mode users saw plain black-on-white code. Added a full light mode token color scheme — keywords in purple, strings in green, functions in amber, comments in muted gray.

Render-Blocking Scripts

Prism.js syntax highlighter and its CSS were loaded synchronously in <head>, blocking first paint. Changed to:

Mobile


The Lesson

For a blog, the index page should be a catalogue, not a firehose. Title, date, description, tags. That’s it. The full content belongs on individual post pages, where they’re cached and served independently.

The highest-impact optimization on this blog was a template change — bigger than any CDN, caching strategy, or script deferral. Sometimes the best performance fix is showing less data.