In Next.js 15, practical gains come from rendering discipline. If you split server and client components correctly, bundle size drops and first render gets faster.
Step one: move everything that does not require browser APIs to server components. Step two: keep only interactivity on the client. Step three: check Lighthouse after each structural change.
Caching must be deliberate. Use revalidate for low-volatility data and no-store for truly real-time data. The key is having a data map, not random cache flags.
A practical pattern is route-level splitting plus lazy loading of heavy widgets. It helps most on mobile and older laptops where CPU is the bottleneck.
Anti-pattern: pushing everything to the client “because debugging is easier.” Cost: slower TTI and higher bounce.
Action plan: 1) route audit, 2) move server logic out of client, 3) optimize images/fonts, 4) enforce web-vitals checks in CI.