Zachoo
Zachoo4w ago

Optimise Fetching data

Hi there! I have an admin dashboard that displays information about users and their apartments. The app includes two lists: one on the /users page that fetches user data and another on the /apartments page that retrieves apartment data, both using the useQuery hook from Convex. However, the app feels slow when switching between these pages. Even though I hit the Convex cache, it still fetches data every time and shows a loading state, which interrupts the experience. Is there a better way to structure this so that moving between pages instantly displays cached data and only updates if the data changes—essentially making it feel like I never left the page?
8 Replies
Convex Bot
Convex Bot4w ago
Thanks for posting in <#1088161997662724167>. Reminder: If you have a Convex Pro account, use the Convex Dashboard to file support tickets. - Provide context: What are you trying to achieve, what is the end-user interaction, what are you seeing? (full error message, command output, etc.) - Use search.convex.dev to search Docs, Stack, and Discord all at once. - Additionally, you can post your questions in the Convex Community's <#1228095053885476985> channel to receive a response from AI. - Avoid tagging staff unless specifically instructed. Thank you!
Zachoo
ZachooOP4w ago
e.g. for page.tsx of /dashboard route i may fetch data as follows
'use client'
import React from 'react'
import { useQuery } from 'convex/react'
import { Card, CardContent, CardHeader, CardTitle } from '@repo/ui/components/ui/card'
import { Loader2 } from 'lucide-react'
import { cn } from '@repo/ui/lib/utils'
import { Building } from '@/lib/global-type'
import { api } from '@packages/backend/convex/_generated/api'
import { BuildingIconPath } from '@repo/ui/components/icons/icons'

export function BuildingOverview() {
const buildings = useQuery(api.buildings.getProjectBuildings)
const user = useQuery(api.users.currentUser)
const bannerImage = useQuery(api.theme.getProjectBannerImage)
'use client'
import React from 'react'
import { useQuery } from 'convex/react'
import { Card, CardContent, CardHeader, CardTitle } from '@repo/ui/components/ui/card'
import { Loader2 } from 'lucide-react'
import { cn } from '@repo/ui/lib/utils'
import { Building } from '@/lib/global-type'
import { api } from '@packages/backend/convex/_generated/api'
import { BuildingIconPath } from '@repo/ui/components/icons/icons'

export function BuildingOverview() {
const buildings = useQuery(api.buildings.getProjectBuildings)
const user = useQuery(api.users.currentUser)
const bannerImage = useQuery(api.theme.getProjectBannerImage)
then on another route e.g. /deliveries I will fetch using
'use client'

import React, { useEffect } from 'react'
import NavigationBar from '../_components/navigation/navigation-bar'
import { PageHeader } from '../_components/global/page-header'
import { ParcelIconPath } from '@repo/ui/components/icons/icons'
import { OccupantMailSummary } from './_sections/occupant-mail-summary'
import { AuthGuard } from '../authProvider'
import { useMutation } from 'convex/react'
import { api } from '@packages/backend/convex/_generated/api'

export default function ParcelsPage() {
const syncDeliveriesSeen = useMutation(api.userAlerts.syncDeliveriesSeen)
'use client'

import React, { useEffect } from 'react'
import NavigationBar from '../_components/navigation/navigation-bar'
import { PageHeader } from '../_components/global/page-header'
import { ParcelIconPath } from '@repo/ui/components/icons/icons'
import { OccupantMailSummary } from './_sections/occupant-mail-summary'
import { AuthGuard } from '../authProvider'
import { useMutation } from 'convex/react'
import { api } from '@packages/backend/convex/_generated/api'

export default function ParcelsPage() {
const syncDeliveriesSeen = useMutation(api.userAlerts.syncDeliveriesSeen)
when the user quickly moves between these pages it still shows a loading state each time while the query completes which makes the app feel slow and clunky
lee
lee4w ago
Can your database do this? Ep. 1: Magic caching
With Convex's magic query cache, Convex's powerful subscriptions are cached, not merely values. So you get fast, jank-free renders with no cache consi...
ian
ian4w ago
And this associated helper discussed in the video: https://www.npmjs.com/package/convex-helpers#query-caching
npm
convex-helpers
A collection of useful code to complement the official convex package.. Latest version: 0.1.67, last published: a month ago. Start using convex-helpers in your project by running npm i convex-helpers. There are 8 other projects in the npm registry using convex-helpers.
Zachoo
ZachooOP4w ago
Bless thanks guys will give it a crack what is update on convex Auth being out of Beta ? I love the convex platform and want to utilise the whole stack.
ian
ian4w ago
You can use Convex Auth in production, but being in Beta means we may change the API going forward, but that wouldn't break existing apps, just may require code modifications when updating the convex-auth version. There aren't current plans for new features soon, so if you're expecting to need 2fa/SSO/etc, you might want to start with something like Clerk
Zachoo
ZachooOP4w ago
@Lee Another quick question this cache looks very cool what are the downside / when should it not be used, to me it seems like this should be the defualt behaviour ?
lee
lee4w ago
the downside would be that the query stays subscribed & re-executing while the useQuery is unmounted. so if there's no chance of re-mounting or the query updates frequently enough that keeping it updated is expensive, you might not want to use the helper. But if you think it's always useful, you should use it 😄

Did you find this page helpful?