djbalin
djbalin6mo ago

useQuery vs one-off query (performance, open connections, etc.)

Hello everyone. I've been thinking about the benefits/tradeoffs of useQuery vs. the imperative/one-off query (https://docs.convex.dev/client/react#one-off-queries) and would love some input. Basically: what are the performance downsides to using useQuery? Does a useQuery e.g. maintain an open network connection throughout the lifetime of its parent component? Is it better/"safer" to default to one-off queries and only opting in to useQuery when we truly need/want e.g. the reactivity or "undefined" loading state that it provides? I am asking specifically in the context of a mobile app using tab navigation: When we navigate from screen to screen using the navigation bar, the non-focused screens/components do not unmount but are kept alive in the background. I was therefore considering if absent-mindedly using useQuery in all these screens would/could lead to a lot of unnecessary open connections and/or overhead. Thank you!
Convex React | Convex Developer Hub
Convex React is the client library enabling your React application to interact
5 Replies
lee
lee6mo ago
As far as connections go, each client maintains a single websocket connection regardless of how many queries it does. The main overhead of keeping queries open unnecessarily is the server keeps you subscribed to updates, which can show up as Convex function calls and network bandwidth (when it changes, the new query result is sent over the websocket). If your query isn't changing much, then both of these costs are moot. In fact, our CEO recently made a library that intentionally keeps queries subscribed for better user experience https://youtu.be/ZgxDlSUGpfE?si=vKksuFXoiP7QF8Cs
Convex
YouTube
Can your database do this? Ep. 1: Magic caching
A Next.js app with no query cache? Jank. One with a cache? No more jank, but now we need to deal with cache invalidation and application consistency. Ugh. But with Convex's magic query cache, Convex's powerful subscriptions are cached, not merely values. So you get the best of both words. Repository here: https://github.com/jamwt/cached-dmv ...
djbalin
djbalinOP6mo ago
Thanks for your quick response @lee ! So, basically, any performance difference between the two approaches is so miniscule that the most pragmatic and reasonable approach is just to use the most developer-ergonomic query method in the given case?
lee
lee6mo ago
Usually yes. There are cases where the data updates so frequently that you want you want to unsubscribe when it's off-screen (this is what the convex dashboard data page does) but that's not common
djbalin
djbalinOP6mo ago
That makes sense! Is there a Convex-way to programmatically/imperatively unsubscribe and resubscribe to a useQuery? Otherwise, my off-the-top-of-my-head solution in React Native would perhaps be to maintain a screenIsFocused state variable and using this to decide whether or not to pass "skip" as an argument to useQuery. How do you handle (un)subscription for the convex dashboard data page?
lee
lee6mo ago
you can do it with "skip" or by conditionally rendering the component that has the useQuery. The dashboard does the latter