-
Notifications
You must be signed in to change notification settings - Fork 10.3k
perf(gatsby): do not force resolvers to be async #28525
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice! Do we have tests in place that test this behaviour to make sure defaultId resolver works as expected?
any, | ||
any | ||
> = function defaultFieldResolver(source, args, context, info) { | ||
function _defaultFieldResolver(source, args, context, info): any { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not keep const & function on same line? Does _defaultFieldResolver still get correct typings?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because then a lint rule of premature usage will trigger, which we do not apply to function declarations.
My attempt failed anyways so I'll change it back and move the whole function instead 🤷
If I throw inside the function and run tests there will be 16 tests that fail where otherwise tests pass. This applies to both return points. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great stuff! This change warrants a comment that we do this for performance reasons. Also, I've added a couple of suggestions inline.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome, thanks! 🥇
Drop the
async
keyword from thewrappingResolver
that wraps all resolvers passed on to graphql. This keyword forces the return value to be a promise, injecting tiny delays in each call. Most of the time you wouldn't notice these but at scale they add up.In this case a large site was triggering the link resolver 35 million times. Only 1.5 million times did the wrapped resolver return a promise. And graphql will properly deal with promises vs non-promises. So we can drop the keyword.
The PR also updates the
linkResolver
to take the fast path (when target key isid
and the resolver is our owndefaultResolver
) sync rather than also force it to be async. ThedefaultResolver
already has noasync
keyword.Doing so drops roughly 5-10% from the runtime of the site I was testing with (!). Promises can be expensive. They should put a warning sign around them.