Not everything needs to be a client component
In the App Router world, default to Server Components. Push interactivity to the edges — menus, forms, carousels, filters — instead of wrapping entire pages in "use client".
Every client boundary downloads JS and pays hydration cost. Ask whether the UI truly needs browser state before you mark it client-side.
Defer non-critical UI
Analytics widgets, chat embeds, and decorative motion should not block first interaction. Load them after primary controls are usable. Prefer idle or post-interaction loading for anything that is not the user’s first job.
Lists, state, and re-renders
Virtualize long lists. Keep state local when only one subtree cares. Avoid cascading context updates on every keystroke. Memoize expensive pure views sparingly — measure first; memo is not free.
Prefer controlled inputs that do not rebuild large trees on each character. Split “search box” state from “results grid” rendering when they update at different rates.
Interaction budgets
Set a simple budget: primary buttons and form fields should feel instant on a mid-range device. Profile with field INP and lab traces on real hardware. A silky desktop demo can still feel sticky on mid-range Android.
Design and engineering together
Interaction quality is a product requirement. Pair UI craft with UI/UX design and web development so motion, layout, and code do not fight each other.