Rendering Blindly Cost Me Speed, Money, and Sanity. Here’s How I Fixed It - Pt 1
Series: Part 1 of Rendering with Intent
Breaking down how I learned to choose rendering strategies intentionally rather than relying on defaults.
WonderBook started as a scrappy build. 'Scrappy' being a generous way of saying 'I had no idea what I was doing, but it compiled.' I just wanted to prove the idea quickly, so I used whatever worked and kept moving. I wasn't trying to design a perfect architecture. I just needed it to function.
But it became a project I actually cared about. I wanted it to feel smoother, load faster and behave like something thoughtfully built rather than quickly assembled.
A few months ago, I realised I didn't properly understand how rendering actually works in Next.js. Which is a polite way of saying I'd been guessing and hoping the framework would save me. I knew pages could run on the client or the server, but I couldn't clearly explain when something should be static, when it should be revalidated or when it needed to render per request. So I went deeper.
Once I understood how static rendering, ISR, server rendering, client components and streaming were designed to be used, I updated WonderBook with a more intentional model. I made decisions based on cost, freshness, security and how often something really needed to change.
The difference was immediate. Pages loaded faster. Database calls dropped. Client-side work reduced. Cached content behaved predictably. The app felt lighter. It made more sense to maintain. Since then, I've treated rendering as a design choice, not a side effect, and I now use the same system across Jobby, my personal site and everything else I build. Deciding where your code runs instead of letting the defaults handle it. What a concept.
Where rendering mattered most
Static pages shipped without hydration. Public story pages were cached with controlled revalidation. Authenticated dashboards were rendered on the server for accuracy and security. High-interaction areas like the story builder lived in the client to support AI-driven real-time updates.
This approach led to measurable gains.
- Explore used ISR and reduced database queries by 83%
- Static legal pages loaded 10 times faster with zero client JavaScript
- Public story pages cached for an hour, improving both load time and link-sharing previews
- SEO improved because critical pages were fully rendered on the server
I’ve applied the same approach across Jobby, my site and every new build since.
Rendering with intent is an architectural discipline
Where your code runs affects things like
- How fast your app feels
- How much JavaScript users download
- How often your database is hit
- Whether search engines can index your content
- How responsive real-time features feel
- Your hosting bill (which will teach you about rendering whether you want to learn or not)
- How sustainable your architecture is over time
Rendering shouldn't be a reflex. It's a tradeoff that comes with consequences. Expensive, slow, user-annoying consequences.
What comes next
In the next parts of this series, I’ll break down each rendering mode by answering two questions
- Why does this strategy exist
- How did I use it in production
Here is the progression we’ll cover
| Rendering Mode | What it prioritises | Best used when… |
|---|---|---|
| Static Rendering (SSG) | Speed and zero runtime | Content rarely changes |
| ISR | Cached freshness | Content updates, but not instantly |
| SSR | Accuracy and personalisation | Depends on user, session or sensitive data |
| Client Components | Real-time interactivity | AI, sockets, local state, voice |
| Streaming and Suspense | Progressive UX | Large or staged data flows |
Rendering is a decision about cost, context and speed, not convenience.
In case you missed the other posts, here they are:
The Rendering with Intent Series
- Part 1: Rendering Blindly Cost Me Speed, Money, and Sanity. Here’s How I Fixed It [You are here]
- Part 2: Static Rendering. Doing the Work Before Anyone Asks For It
- Part 3: I Wanted Static Speed Without Serving Yesterday’s Data. ISR Was the Answer
- Part 4: Switched to SSR When “Good Enough” Started Causing Real Problems
- Part 5: When Static Pages Weren’t Enough, Client Components Took Over
- Part 6: I Made Data Feel Faster Without Actually Speeding It Up