Slow overlapping queries due to MissingFieldError invariants
See original GitHub issueIntended outcome: Concurrent queries should about as fast as separate queries.
Actual outcome: I have a use case where two queries are fired on startup for the same objects but different fields. I noticed that the first one was particularly slow to receive, normalize and update the store, taking over 2.6s, while the second one is faster, taking about 400ms. When looking at the trace the majority of the time is spent building MissingFieldError invariants (https://github.com/apollographql/apollo-client/blob/b0da267d24d8713987e9ff8d2240c5c7ed94eb94/src/cache/core/types/common.ts#L21-L33).
(trace)
(zoomed in)
(bottom up stack)
It looks like what is happening is the first query requests one set of fields (~100 fields * 200 objects), the second requests a much larger set of fields not contained in the first query (~200 fields *200 objects). Then when the first query completes it normalizes the results and hits MissingFieldError for the missing fields from the second query which hasn’t been processed yet, causing a huge performance bottleneck due to the invariants.
When I run both queries individually they only take 300ms and 400ms respectively. If they’re fired at the same time I hit this problem.
How to reproduce the issue: Send two large queries with overlapping queries. The second queries should contain a lot of fields that aren’t present in the first query. The first query should be processed and normalized first.
Versions
System:
OS: macOS 11.4
Binaries:
Node: 14.17.3 - /usr/local/bin/node
Yarn: 1.22.10 - ~/universe/webapp/web/node_modules/.bin/yarn
npm: 6.14.13 - /usr/local/bin/npm
Browsers:
Chrome: 92.0.4515.159
Firefox: 89.0
Safari: 14.1.1
npmPackages:
@apollo/client: 3.4.9 => 3.4.9
apollo: ^2.31.1 => 2.31.2
apollo-link-queue: ^3.1.0 => 3.1.0
apollo-link-rest: 0.8.0-beta.0 => 0.8.0-beta.0
apollo-utilities: 1.3.2 => 1.3.2
Issue Analytics
- State:
- Created 2 years ago
- Reactions:3
- Comments:11 (3 by maintainers)
Top GitHub Comments
Thanks, it’s certainly a fun perf problem to work on.
FWIW a lot of the time is spent in
super(message);
so a quick mitigation could be to just not extend Error if nothing else relies on it. I bet a lot of the time is spent grabbing JS stacks for those errors. Merge these into one would also fix the bottleneck.I couldn’t see where these invariants went but I didn’t trace that code.
Sorry I don’t have a repro for you but I’ll happy test any PRs.
Bisected to migrating from
.cjs.js
to.cjs
in https://github.com/apollographql/apollo-client/commit/f5a7a58bf7c054f09b02a73cab80559544e7cf07. Heads up in case others see issues while migrating.