Skip to content
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

Update RFC to GraphQL Defer and Stream #679

Closed
wants to merge 1 commit into from

Conversation

Keweiqu
Copy link
Contributor

@Keweiqu Keweiqu commented Jan 30, 2020

Provide alternative solution comparison, highlighted value prop and use case guidance with @defer and @stream.
With @jhusain, @JenniferWang and @tcr.

Provide alternative solution comparison, highlighted value prop and use case guidance with @defer and @stream.
@Keweiqu Keweiqu changed the title Update DeferStream.md Update RFC to GraphQL Defer and Stream Jan 30, 2020
@Keweiqu
Copy link
Contributor Author

Keweiqu commented Jan 30, 2020

Some additional questions would love discuss during the working group meeting:

  • Should we leave @defer in favor of a more declarative directive in the future?
    The specification of @defer suggests an imperative paradigm where the fragment marked with @defer has to be deferred (i.e. asynchronously eagerly delivered). It’s unclear if this is the best decision long term. It may be efficient and performant to deliver along with initial payload (eagerly and synchronously) in some cases, and may be better to not deliver at all and issue a follow-up query to fetch deferred part (lazily and asynchronously) in other cases.
  • Following the guideline of "Possible but awkward" is often favored over more complex alternatives, some components of @defer and @stream left out from this RFC. Would love to get opinions on if any of the components would be valuable to be included in the spec:
    • Batched Payloads: With incremental delivery, where multiple responses are delivered in one request, client-side could rerender multiple times in a short period, putting a lot of pressure on the battery. A practical workaround is two-render, where the client-side renders once for the initial response and rerenders again when all subsequent responses are delivered.
    • "If" Argument for Easier A/B test setup: In order to switch between regular and @defer/@stream mode, we would need to duplicate the field/fragments in question and annotate it with @defer @include(if: $try_defer) and @Skip(if: $try_defer) respectively. This works in most cases but not ideal in terms of developer experience.
    • “is_fragment_fulfilled” Client Developer Facing API: Often times, developers would like to show different UI, say a loading spinner, based on the fulfilling state of the @defer fields. Since each GraphQL field is nullable, we cannot faithfully report the fulfilling state of the deferred fragment without generating some metadata upfront. This can be achieved by generating a boolean client side field say, "is_fragment_fulfilled" for each @defer annotation. Upon receiving incremental payload, client infra can flip the corresponding client side field. However, there is a problem with the "If" argument we just mentioned -- what if we are in the control group where "If" is false? One solution is to let server send back the paths of fulfilled @defer together with the payload.
  • Formalization of request/response/payloads?
  • Use case challenges are valuable for developers using @defer and @stream but do not affect implementers as much. What would be a good channel to share these additional context?
    • stream connection cursor dependency: When a developer wishes to stream a paginated list through GraphQL connection abstraction, the page_info field usually needs to be marked with @defer if the backend is using cursor-based pagination. Since resolving the cursor depends upon the resolution of the last element in the current page, even if we stream the page elements, cursor resolution remains the bottleneck of the query execution time. Hence, in a use case of forward pagination, “end_cursor” and “has_next_page” need to be marked with @defer to improve latency.
    • @defer/@stream and GraphQL subscription: Often times, an App surface needs both incremental delivery and subscription to work hand in hand to deliver the best user experience. We use incremental delivery to ensure the initial render happens as fast as possible for users to start interacting with the App and use subscription to keep the data up to date. However, if a client receives interleaving responses from incremental delivery and subscriptions, it may result in confusing behavior due to inconsistent data. Therefore, we recommend only establishing the subscription connection after the incremental delivery response stream is complete.
    • Perceived slowness: UX research has found that user-perceived slowness matters more than the actual performance of the App. Most of the time, perceived App performance and the actual performance are aligned. However, when rerender changes the layout or location of the existing components, users perceive the App as slower than it actually is. Incremental delivery, especially @defer, is likely to change the hierarchical component structure after additional data is merged into the original response. We suggest treating @defer as a low-level infrastructure API that integrates with rendering framework to make sure that deferred responses do not change the existing components hierarchy or location, instead of exposing @defer directly to client-side developers.

@IvanGoncharov
Copy link
Member

@Keweiqu @robrichard If this PR is still relevant, if so can you please rebase it?

@robrichard
Copy link
Contributor

@IvanGoncharov this can be closed, these changes have been added to rfc docs

Base automatically changed from master to main February 3, 2021 04:50
@leebyron leebyron force-pushed the main branch 4 times, most recently from e5d241d to 6c81ed8 Compare April 23, 2021 19:15
@leebyron leebyron closed this Sep 2, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
📣 RFC document PR creates or changes document inside "rfc" folder
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants