-
-
Notifications
You must be signed in to change notification settings - Fork 460
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
RFC: Memoize the printing of queries #2787
Comments
The thing that I fear here is exchanges that alter the |
Hey Jovi 👋 I know the cache exchange and graphcache exchange insert This may be my misunderstanding of directives but I thought they were typically always included in a query but then evaluated based on the value of a variable. But are you saying that exchanges might conditionally alter a query to add or remove directives? Wouldn't that already present a problem for the existing |
I was mainly referring to what if someone writes an exchange that looks at a query string and looks for |
Hey Jovi, could you please help me understand this issue? Let's call this hypothetical exchange Local Exchange. If the Local Exchange removes It seems like it would already be problematic today for an exchange to conditionally alter a query if that exchange is positioned before the cache or graphcache exchange. These exchanges pass the query through the formatDocument util which already memoizes the mutation it performs on the query. So I can't quite see how memoizing the print of the query in the fetch exchange would be any different to this. |
This is already implemented. I think the concern here was to accidentally reuse printed strings of ASTs that have been mutated rather than cloned, but eventually we discovered that the possibility of this is rather irrelevant, and I believe this was then introduced without much disruption. As per this, the result of the Furthermore, parsing is already pretty optimised to prevent parsing the same string multiple times as much as possible. That said, we'd assume that in optimised applications where this process is necessary, ASTs would already exist as pre-parsed JSON objects and this would become irrelevant. In that case, we indeed store the Lastly, This property was explicitly chosen and is used to make sure that any spread/cloned AST would still yield the same result, making any "wrong" stringification obvious while also surfacing how we'd expect the AST to at least have a new root So, I'm inclined to close this as "completed" 😅 On a side note, having done extensive benchmarks on almost every part of Edit: Ah, I just read your change on: https://github.com/FormidableLabs/urql/blob/30ecefe9f69a4c33849f6c9c43bf5083b35878c2/packages/core/src/internal/fetchOptions.ts#L17 Hm, I believe the reason why we had to remove this was due to this protection not originally existing: https://github.com/FormidableLabs/urql/blob/30ecefe9f69a4c33849f6c9c43bf5083b35878c2/packages/core/src/utils/request.ts#L24-L28 But these days it should be save to replace with The only problem I see here is that this is a breaking change. I'm not really willing to duplicate a small cache for the print output rather than reusing We could add an extra check for Edit 2: This could look like the following: main...fix/stringify-in-body But this will potentially introduce extra work if any other GraphQL utility happens to try to prevent future Edit 3: (Yes, a lot of edits down the line) So, it may be simplest to just expose an extra way for us to reuse |
Thanks for all that info @kitten!
How would this break the persisted fetch exchange? I understand that the persisted fetch exchange hashes the request body query, and we need to have deterministic hashes for APQ. But changing Edit: also, we're using |
Because we'd need to hash the output of a parsed then printed AST, i.e. a normalised output. However,
Just to clarify what I said, the memoisation would still work — however, we wouldn't be able to trust the Also, even in your setup, as you're describing it, I'd suspect |
Hi @kitten, shall I close this issue and open a bug issue instead for clarity, linked to this? |
I made some progress on this and found a stable set of redactors that should satisfy all the requirements we have. However, there'll be plenty of moving parts to test, e.g.
After that's done this should be good to go |
Thanks! |
Summary
✌️ @jian-ong
We note that the
formatDocument
util uses memoization to avoid walking over the same query AST multiple times:https://github.com/FormidableLabs/urql/blob/30ecefe9f69a4c33849f6c9c43bf5083b35878c2/packages/core/src/utils/typenames.ts#L64
In our application we have observed a similar bottleneck with the
print
function from thegraphql
module. Many pages use the same query with different variables, but they are all having to print the exact same query.Proposed Solution
We propose adding a
Map
to themakeFetchBody
function to memoize printing of GraphQL queries in a similar way to theformatDocument
util.Example implementation:
7edb1e2
We are keen to hear your feedback on this. Are there other use-cases where this would be a problem, for example queries being constructed dynamically at runtime, resulting in different query keys, or is that not a supported use-case?
The text was updated successfully, but these errors were encountered: