#Understanding context selector performance impact

2 messages · Page 1 of 1 (latest)

solemn needle
#

Hi! I'm debugging some performance issues and I'd like to understand why A performs worse than B?

// A. use selector
  const { queryOptions } = Route.useRouteContext({
    select: (context) => ({
      queryOptions: context.trpc.organizations.projects.getData.queryOptions({
        organizationId: context.organization.id,
        projectId: context.project.id,
      }),
    }),
  });
  const query = useQuery(queryOptions)

// B. no selector
  const context = Route.useRouteContext();
  const query = useQuery(
    context.trpc.organizations.projects.getData.queryOptions({
      organizationId: context.organization.id,
      projectId: context.project.id,
    })
  );

For the record:

  • "A" causes a lot of rerenders
  • I created my router with defaultStructuralSharing: true (because I thought that would cover this exact case)

Is that because the shape of the object changes all the time (maybe because of functions returned by queryOptions)? Thanks for your help

Please ping me!

carmine jackal
#

I think your guess about "because of functions" might be right on the money. Maybe you could have a combination of both like below. The selector is only useful if stuff is likely to change a lot anyway. For a useSearch it makes a lot of sense. For a useRouteContext, maybe it's overkill, and your "B" solution is actually the best way to do this.

const {trpc, options} = Route.useRouteContext({
  select: (context) => ({
    trpc: context.trpc,
    options: {
      organizationId: context.organization.id,
      projectId: context.project.id,
    }
  })
});
const query = useQuery(
  trpc.organizations.projects.getData.queryOptions(options)
)

Idk if that's much better in terms of ergonomics.