T
TanStack4mo ago
inland-turquoise

Understanding context selector performance impact

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,
})
);
// 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!
2 Replies
foreign-sapphire
foreign-sapphire3mo ago
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)
)
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.
inland-turquoise
inland-turquoiseOP3mo ago
Thanks for confirming!

Did you find this page helpful?