zino-hofmann / graphql-flutter

A GraphQL client for Flutter, bringing all the features from a modern GraphQL client to one easy to use package.
https://zino-hofmann.github.io/graphql-flutter
MIT License
3.25k stars 620 forks source link

Provide more control on when queries are executed #1168

Closed ZRunner closed 2 years ago

ZRunner commented 2 years ago

I recently had an issue in my Flutter app where I realized that, in some situations, a GraphQL query could be executed dozens of times per second. It appeared to me that these executions were triggered by the reconstruction of the widget containing them, itself triggered by the appearance or disappearance of the keyboard (this is a well-known behavior with iOS, see also here).

While the dozens of rebuilds triggered by a keyboard change on iOS has been considered as a bug, and some work is being done to reduce the amount of rebuilds, the fact that a widget can be rebuilt up to 60 times per second (and 120 for some devices) is normal and expected. Many sources insist that the build method must be idempotent, i.e. it must not change anything in the state of the widget or make expensive calls or calculations. For example, retrieving data from an external API, or performing expensive calculations, can be done at widget initialization.

However, it seems to me (from my 2 months of learning Flutter and React Native) that this principle is not respected by this GraphQL library. If the cache strategy is set as "cache and network" or even "network only", the requests will be executed at each rebuild, up to 60 times per second.

So I would like a better way to control the execution of my GraphQL queries. For example with a specific cache method that will not make any network call if the cache version is less than X seconds/minutes old, or by allowing queries outside the build method.

If such a solution already exists, it would be interesting to highlight it in the library documentation.
But if it is technically impossible, I am very curious to try to understand why (since Flutter is the main subject of my current internship) and I would welcome any workaround to avoid having 200 requests in a few seconds.