Back to Insights Blog/Building Fast: Next.js 16 App Router Performance Strategies for AI Applications
ArchitectureMay 12, 20265 min read

Building Fast: Next.js 16 App Router Performance Strategies for AI Applications

AI-powered web apps have unique performance challenges — large streaming payloads, client-side state synchronisation, and animation-heavy UIs. Here are the patterns that keep Netbritz subsidiaries running at 60FPS with sub-second first loads.

N

Netbritz Frontend Guild

UI & Performance Engineering

Why AI Apps Have Unique Performance Challenges

Standard web applications have well-understood performance patterns — minimise bundle size, cache aggressively, defer non-critical scripts. AI-powered applications add several new complications:

- **Streaming responses**: LLM outputs arrive token by token. The UI must update in real time without repaints causing layout thrash. - **Client-side state**: Conversation history, token balances, and session context require careful state management. - **Animation density**: Premium dark-themed UIs with glassmorphism effects and micro-animations are GPU-intensive on lower-end devices. - **Cold-start latency**: Serverless API routes that invoke LLM APIs have meaningful cold-start times if not kept warm.

Here are the strategies we use across Netbritz applications.

Strategy 1: Server Components by Default, Client Components by Exception

Next.js 16 App Router makes React Server Components (RSC) the default. For AI applications, this is powerful: static layout, navigation, section headers, and non-interactive content all render on the server and ship zero JavaScript to the client.

The 'use client' directive should appear only on components that genuinely require interactivity: animation components, chat input boxes, real-time streaming displays, and modal dialogs.

A common mistake is marking entire page files as 'use client' to use one interactive widget. Instead, extract the interactive part into its own component and import it into a server component parent.

Strategy 2: Framer Motion Performance Budget

Framer Motion is excellent — and expensive if used carelessly. Our rules:

- 'willChange: transform, opacity' on every animated element. This promotes the element to its own GPU compositor layer before the animation begins, eliminating jank. - 'viewport={{ once: true }}' on scroll-triggered animations. Re-triggering animations every time a user scrolls past is visually noisy and wastes CPU. - Never animate width, height, top, left, or margin. These trigger layout recalculation. Always animate transform: translateX/Y/Z and opacity only. - Use useSpring for physics-based continuous motion (scroll progress bars), not animate. Spring values are interpolated natively by the browser.

Strategy 3: Streaming UI for LLM Responses

Do not wait for the complete LLM response before rendering. Use React's Suspense and streaming-compatible data fetching to display the first tokens as they arrive.

In Next.js 16, Server Actions that return streaming responses can be consumed with the useActionState hook and React's Suspense boundaries — showing a typing indicator immediately, then populating the response progressively.

Strategy 4: Zustand for Global AI State

Avoid using React Context for frequently-updated AI state (token counts, current session, streaming content). Context triggers re-renders on all subscribed components on every update — catastrophic for streaming text that updates dozens of times per second.

Zustand with selector-based subscriptions ensures only the component displaying the current token count re-renders when that count changes, not the entire application tree.

Strategy 5: Image and Asset Optimisation

Use Next.js Image with priority for above-the-fold images. For AI-generated or user-uploaded content, implement blur placeholder hashes to prevent layout shift. Background gradient blurs (used extensively in glassmorphism UIs) should be applied with CSS filter: blur() on static div elements — not on animated ones — as CSS blur is composited more efficiently than Framer Motion's blur property.

Measuring What You Optimise

Every performance change should be measured with Core Web Vitals: LCP (Largest Contentful Paint), CLS (Cumulative Layout Shift), and INP (Interaction to Next Paint). The Next.js Analytics integration and Chrome DevTools Performance panel give you the ground truth.

Do not guess. Measure, change one thing, measure again.

Parent AI Ecosystem Spotlight

Explore Legal Adviser Platform

Try Uganda's leading AI legal assistant with verified statutory citations and voice support.

Launch Legal Adviser ↗