Stop 19 · Frontend System DesignTopics · 13/13

Performance Architecture

Part of the Frontend Developer Roadmap

In short

Most slow apps are slow because of early choices: what renders where, how much JS ships and how data is fetched. Making those choices on purpose beats patching later.

Making performance a first-class architectural concern — rendering strategy, code splitting boundaries, and data-fetching patterns chosen upfront rather than patched in later.

The jaadu in a hard hat points at a wide new flyover with cars flowing underneath.

Think of it like this

Planning the road before the traffic

A city that plans flyovers and wide roads early handles traffic easily. One that adds them after the jam has to dig up everything. Performance works the same way: decide rendering, splitting and data flow before the app grows.

Watch it happen

Loading the heavy chart only when needed

Browser
Server
Chart chunk

GET /reports

1/6The user opens the reports page.

The big ideas

What you need to know

Choose rendering per page

Static pages for content, server rendering for personalised pages, client rendering for highly interactive screens.

Split code by route

Each page loads only its own JS. Heavy widgets like charts or editors load when needed.

Set performance budgets

A budget is a limit, like a max JS size per page. CI fails when a change goes over it.

Measure real users

Track Core Web Vitals (LCP, INP, CLS) from real visits, not just your fast laptop.

How it works

Designing a fast page

  1. 1

    Pick rendering

    Decide static, server or client rendering based on how fresh and personal the data is.

  2. 2

    Plan the data

    Fetch on the server where you can, and avoid request chains that wait on each other.

  3. 3

    Split the bundle

    Lazy-load below-the-fold and rarely used features.

  4. 4

    Set a budget

    Agree on size and Web Vitals limits and add a CI check.

  5. 5

    Watch real users

    Monitor field data and fix what actually hurts people.

See it in code

Walk through the code

tsx
1"use client";2import dynamic from "next/dynamic";3 4// The chart library downloads only when this component renders5const SalesChart = dynamic(() => import("./SalesChart"), {6  loading: () => <p>Loading chart…</p>,7  ssr: false,8});9 10export function ReportsTab() {11  return <SalesChart />;12}

1/4dynamic with ssr: false must be used in a Client Component.

Heavy libraries like charting packages stay out of the first page load. Users who never open the Reports tab never download them.

Save yourself the pain

Common mistakes

Oops

Making every page client-rendered because it's what you know.

Do this instead

Choose per page. Content pages are often faster as static or server-rendered HTML.

Oops

Only testing speed on your own laptop with fast Wi-Fi.

Do this instead

Throttle to a slow mobile network in DevTools and check real-user data, since many users are on budget phones.

Your mission

Put your app on a diet

~35 min

Quick check

Your blog's article pages are client-rendered and show a spinner before any text appears. What's the best architectural change?

Go deeper

  1. 1Decide your rendering strategy (SSR/SSG/CSR) per route before building it, not after.
  2. 2Set a performance budget (e.g. bundle size, LCP target) for the project.
  3. 3Review architectural decisions periodically against real Lighthouse/Web Vitals data.

More topics at this stop

Stuck on this topic? Ask an Insider

Get 1:1 guidance from people who've walked this exact path — on the InsideEdge app.

Download
InsideEdge