dillonkearns / elm-graphql

Autogenerate type-safe GraphQL queries in Elm.
https://package.elm-lang.org/packages/dillonkearns/elm-graphql/latest
BSD 3-Clause "New" or "Revised" License
778 stars 107 forks source link

Building large queries takes a long time and pauses the UI #632

Open hephaistos-official opened 1 year ago

hephaistos-official commented 1 year ago

In my use-case I've got a few fairly large SelectionSets (>1 MB when serialized to string as part of a HTTP POST) and when I try an do a query that has six similarly large SelectionSets the UI entirely pauses for a few seconds. Having profiled this, it appears that the cause of this is the Graphql.Document.serializeQuery function.

Is there a way to do the query serialization in a way where it doesn't pause the UI? Alternatively, since the SelectionSet doesn't change in my case, is there a way to "cache" the serialized query and use it the next time rather than having to re-serialize it every time?

dillonkearns commented 1 year ago

You can use the low-level functions https://package.elm-lang.org/packages/dillonkearns/elm-graphql/latest/Graphql-Document#serializeQuery to manage serializing the query and caching the query string and https://package.elm-lang.org/packages/dillonkearns/elm-graphql/latest/Graphql-Document#decoder to get the decoder from it.

I'd welcome a PR with performance optimizations to Graphql.Document.serializeQuery if you're interested in experimenting with that. There's a pretty robust test suite around it so there might be some low-hanging fruit there, and you can get a pretty good feedback cycle to experiment with things with those tests running.

hephaistos-official commented 1 year ago

Thanks for the reply, and (I should've mentioned this in the original comment) this wonderful graphql client library!

Using serializeQuery seems to do the trick, but while exploring that API I noticed that all the functions deal with RootQuery and RootMutation, and there isn't a way to serialize with placeholder GraphQL variables (eg. $ids). So, right now I still have to re-serialize when my variables change.

Is there a way to serialize SelectionSets with non-root Scopes? and, is there a way to specify GraphQL variables when serializing so I can reuse the resultant string with many different variables?