Performance
Remove unnecessary query stages, reduce payloads, and measure the Nuxt-to-Convex lifecycle.
Optimize the lifecycle you actually use. Do not add another cache before identifying the expensive stage.
Recommended order
- Measure SSR, navigation, payload size, and subscription activity.
- Disable a lifecycle stage the page does not need.
- Return less data and paginate growing collections.
- Avoid unnecessary auth work on public paths.
- Tune deployment and auth verification from evidence.
Remove unnecessary SSR
Use server: false for browser-specific data that does not improve the initial HTML.
await useConvexQuery(api.presence.current, {}, { server: false })The cost is a browser loading state and no server-rendered value.
Remove unnecessary subscriptions
Use subscribe: false for stable snapshots and reports:
await useConvexQuery(api.reports.monthly, args, { subscribe: false })The result will not change until refresh() or navigation runs it again.
Keep public data independent of auth
auth: 'none' skips auth settlement and always uses anonymous transport. Use it only for functions whose result and authorization are truly identity-independent.
Bound result size
Return fields the page uses. Use indexes and take() for bounded lists. Use pagination for growing collections. Large SSR results increase Convex work, HTML/payload size, parsing, and hydration cost.
Understand duplicate dashboard calls
The default SSR-to-live lifecycle creates one server HTTP query and one browser subscription. This is not a duplicate subscription bug. Disable a stage only when its product benefit is unnecessary.
Avoid a mirrored store
Copying Convex entities into Pinia adds update and identity-clearing work. Use normal or shared queries and keep stores for UI-only state.
Measure production behavior
Development includes HMR, DevTools, source maps, and extra diagnostics. Use production builds and representative deployment regions before drawing latency conclusions.