Skip to content

Instantly share code, notes, and snippets.

@vagusX
Forked from acdlite/coordinating-async-react.md
Created September 19, 2017 01:58
Show Gist options
  • Select an option

  • Save vagusX/ad918c6f3b6162f34c966405f5a01e65 to your computer and use it in GitHub Desktop.

Select an option

Save vagusX/ad918c6f3b6162f34c966405f5a01e65 to your computer and use it in GitHub Desktop.

Revisions

  1. @acdlite acdlite revised this gist Sep 19, 2017. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion coordinating-async-react.md
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,6 @@
    # Demo: Coordinating async React with non-React views

    **tl;dr I built a [demo](https://build-mbfootjxoo.now.sh/) illustrating what it might look like to add async rendering to the UFI, while ensuring it appears on the screen simultaneous to the server-rendered story.**
    **tl;dr I built a [demo](https://build-mbfootjxoo.now.sh/) illustrating what it might look like to add async rendering to Facebook's commenting interface, while ensuring it appears on the screen simultaneous to the server-rendered story.**

    A key benefit of async rendering is that large updates don't block the main thread; instead, the work is spread out and performed during idle periods using cooperative scheduling.

  2. @acdlite acdlite revised this gist Sep 18, 2017. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions coordinating-async-react.md
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,5 @@
    # Demo: Coordinating async React with non-React views

    **tl;dr I built a [demo](https://build-mbfootjxoo.now.sh/) illustrating what it might look like to add async rendering to the UFI, while ensuring it appears on the screen simultaneous to the server-rendered story.**

    A key benefit of async rendering is that large updates don't block the main thread; instead, the work is spread out and performed during idle periods using cooperative scheduling.
  3. @acdlite acdlite created this gist Sep 18, 2017.
    47 changes: 47 additions & 0 deletions coordinating-async-react.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,47 @@
    **tl;dr I built a [demo](https://build-mbfootjxoo.now.sh/) illustrating what it might look like to add async rendering to the UFI, while ensuring it appears on the screen simultaneous to the server-rendered story.**

    A key benefit of async rendering is that large updates don't block the main thread; instead, the work is spread out and performed during idle periods using cooperative scheduling.

    But once you make something async, you introduce the possibility that things may appear on the screen at separate times. Especially when you're dealing with multiple UI frameworks, as is often the case at Facebook.

    How do we solve this with React?

    You can think of React rendering as being split into two main phases:

    - the *render phase*, where we compare the new tree with the existing tree and calculate the changes that need to be made. This phase is free of side-effects, so it can be done asynchronously. The work can also be interrupted, rebased, restarted, and interleaved with other updates.
    - the *commit phase*, where the changes computed during the render phase are flushed to the screen. This phase is typically very fast and is performed synchronously to avoid inconsistencies.

    Because these two phases are separate, we can expose an API to the developer to control exactly when the commit phase is executed. Before then, the async work can be completed, but nothing is actually updated on the screen. That way we can coordinate React's commit phase with non-React renderers.

    The new API will look like this:

    ```js
    const root = ReactDOM.unstable_createRoot(containerEl);
    const work = root.prerender(<App />);
    // ... other async work ...
    work.commit();
    ```

    You can also await `work` to ensure that the render phase is complete. (If you don't, the remaining work is flushed synchronously, which may or may not be what you want.)

    ```js
    const work = root.prerender(<App />);
    await work;
    work.commit();
    ```

    Another neat feature is the ability to start rendering before the DOM container is even available:

    ```js
    let containerEl;
    const root = ReactDOM.unstable_createLazyRoot(function getContainer() {
    return containerEl;
    });
    const work = root.prerender(<App />);
    containerEl = await promiseForContainer;
    work.commit();
    ```

    Play around with the demo and [see for yourself](https://build-mbfootjxoo.now.sh/)! Hopefully this helps illustrate how async rendering in React can be used to build products.

    We'll share more demos and examples in the future.