/suspense-concurrent-mode

Notes and demo code for talk

Primary LanguageJavaScript

Intro

  • Suspense and Concurrent Mode help improve user experience when CPU or IO is lagging
  • Also improves user experience when CPU/IO is fast (minimizes flash of loading spinners/jankiness which cause reflows and slower perceived user experience)
  • Allows a web app to feel like a fast & fluid native app with smooth responsive transitions
  • facebook is building v5 of their site on these features and it looks awesome
    • experimental but already used in complex app that serves billions of users

Suspense

  • Initial impression = just makes loading logic a bit easier, but in a bizarre way (throwing promises)
  • Much more than that
  • Inversion of control (child declares data dependencies) keeps components isolated and modular
  • Parent or previous screen is completely agnostic of data needs - whether the child/next screen needs to suspend waiting for code-split components to load, images, data, or other assets. Doesn't care. Enables loose-coupling
  • Can be used separately from concurrent mode, but in conjunction with concurrent mode, it faciliates some interesting patterns that significantly improve user experience (such as remaining on current screen and staying responsive to user input while rendering next screen in memory (creating dom nodes and running user code in components))
  • Similar to declarative error boundaries:
    • https://jsfiddle.net/491na827/1/
    • Code also in this repo
      • error boundary will show in development. Click x on error overlay or escape
      • or just run build version: yarn run build && serve -s build
  • Suspense Boundaries function like a try...catch:
  • React DevTools let you toggle suspending state of components to test out your boundaries:

Concurrent Mode

What causes janky unresponsive screens?

How Concurrent Mode works

  • Many names: async rendering, time slicing, and now concurrent mode
  • UI frameworks today have to complete rendering on state change before responding to user input
  • React Concurrent Mode keeps screen responsive
  • Splits up rendering into units of work and intermittently yields back to browser to handle user events: React concurrent mode
  • Think of it like a git branch. It works on new UI changes in memory and only commits to "master" (the actual DOM) when all the changes are ready
  • babel converts your JSX expressions at build time to virtual dom elements, react reconciles/diffs the virtual dom elements with actual dom nodes, and then commits the changes to dom
  • You may have heard this word "fiber" before. Before "fiber" architecture, React would recursively render all your virtual dom elements and their children. Rendering was not interruptible because each recursive call got pushed to call stack and they all had to run at once: Recursive call stack
  • Fiber architecture introduced a "fiber" data structure that allows react to render converted JSX elements in same order as recursive algorithm, but in a while loop that is interruptible so react can intermittently yield back to browser to stay responsive:
  • DEMO interruptible fiber algorithm
    • code also in repo in fiber-demo folder
  • Fibers loosely-correspond to components and have pointers to child, parent, and sibling (like a linked list) fiberstructure Fibers
  • Fibers also enable stateful functional components because react internally associates your useState and useEffect hooks with the currently rendering fiber

Data Fetching Patterns

Other implications

Official Docs