GraphQL Shield response 2times slower on response with large list
See original GitHub issueBug report
- I have checked other issues to make sure this is not a duplicate.
Describe the bug
When i return a large document with a array (1000+ elements) it increases response times with almost factor 2 with GraphQL running. When i remove GraphQL shield from the ApplyMiddleware the response time is greatly reduced.
To Reproduce
Have a object with a large list of around 1Mb. Return it with GraphQL shield enabled and disabled and see the differences
Expected behavior
I expect milli second slowdown because of rule check, it looks like every element of the schema is checked. (if so can i disable this is certain types?)
Reproduction
A codesandbox can be found here: https://codesandbox.io/s/gracious-dust-55156?file=/index.js On code line 77 comment out “permissions” use the graphQL playground to see the differences in speed.
use the following query:
{ hello { id start end numbera mainitems{ numbera floata floatb floatc floatd floate items { floataa floatbb numberaa floatcc numberbb timestamp subobj{ floataaa floatbbb } } } } }
Issue Analytics
- State:
- Created 3 years ago
- Comments:10
Top GitHub Comments
If anyone’s still bothered by this, I’ve figured out a way around the problem.
According to the documentation, there are three values you can specify for the caching option:
no_cache
,contextual
andstrict
. It is suggested that you use thestrict
option if the resolution of your rule depends on theparent
orargs
parameter. The problem is that when usingstrict
, the cache key is a hash generated from the entireparent
andargs
objects. This is both rather slow for large objects and data sets and too strict, because in my case at least, there are no identical combinations ofparent
andargs
, even though the sameparent
might in fact be referenced, I just define “same” differently.It turns out there is a fourth caching option: You can pass a function that returns the cache key the rule should use. In my case, I could simply use
cache: (parent) => parent.id
and that was that. All the permissions I set still work and all my requests are 2-5 times faster.I hope I could save someone some headache with this.
If anyone is still experiencing this problem, I found a hacky solution.
I’ve found that my performance issue was that graph QL shield wrap even defaults resolvers in async functions to handle permissions and errors. In my case since I do not need the error handling and my fallback rule is “allow”. I found that keeping only the part of the shield middleware I explicitly define does is faster and still validates the rules I need.
Here is how I removed them: https://codesandbox.io/s/dreamy-brahmagupta-vr8ysw?file=/index.js.