Performance

  • React Conf 2017 (~3/2017) (React v16 release = 9/2017)

    • Day 1

      • Keynote

        • Part 1 (~6min): Tom Occhino

        • Part 3 (~18min): Sebastian Markbage - React Performance End to End (React Fiber)

          • Enhancing performance:

            • CSR & SSR = best (not an all or none approach -- CSR/SPA popular at the time)

            • Briefly mentions the benefit of a React compiler

            • Mentions streaming

            • Concept of rendering "priority levels" (low/high)

            • ...aka, "scheduling is a core primitive of UI engineering"

              • at the time:

                • very ad hoc solutions for this (threads, workers, built-in primitives), all with their own benefits/tradeoffs

              • final solution:

                • "React Fiber" (React v16)

                  • complete reimplementation of the core algorithm inside React (with ground-up support for built-in scheduling)

                    • "A New Foundation"

                    • (Lin Clark has a talk about how it works under-the-hood)

                  • built with full backwards compatibility

                  • launched in "compatibility mode" by default (with an opt-in for asynchronous interruptible rendering -- "asynchronous mode")

                    • future versions = "asynchronous mode" by default

        • Part 4 (~6min): Tom Occhino - React Fiber, Create React App (CRA), React Community

          • <ErrorBoundary />

            • (failing in an isolated way, and handle gracefully; wrap components)

          • Ability to return multiple components from "render"

            • (can return arrays & strings now)

          • React Fiber = entirely written in Flow

            • (easier to follow core React code, make contributions, etc.)

          • CRA introduction

            • (CLI for spinning up a react app -- create-react-app)

      • (~30min) Lin Clark - A Cartoon Intro to Fiber

        • Fiber (Fiber reconciler)

          • improves perceived performance & responsiveness to React apps

          • = new reconciliation algorithm

            • History

              • React's "main thing" when it came out = vDOM

                • made coding UI much easier

                  • instead of telling browser how to go from current version to next version, just tell React what next version should look like

                    • (makes UI easier for not just DOM, but all platforms -- native apps, VR, hardware, ...)

            • Reconciler vs Render

              • renderer = pluggable

                • (can use any from community to target host platforms besides DOM)

              • reconciler = only one (React's)

            • High vs Low priority updates (Fiber handles this)

              • Note:

                • for fluid motion/UI updates, need 60fps (16ms per frame)

                  • React updating is fast enough to do this, but often "larger update" user code ends up coming in and blocking it (mostly due to render function & other user code functions)

                    • "updates" = React updates, browser updates (CSS animations, browser resizes)... all would get trapped behind "larger updates", due to all being on a single/main thread

                    • Solution = make updates "play together" better (high/low priority updates)

              • With Fiber, React knows how to "work better" with the main thread

                • minimizes & batches DOM changes

                  • how to split up work, how to prioritize work

                  • watch (keep track of how much time has passed)

              • Reconciliation

                • Elements, Instances, Dom

                • Old reconciler ("stack reconciler"; retroactively given a name):

                  • one after the other ("layer by layer") (create Element > update Instance > update DOM node)

                    • recursively calls updateComponent or mountComponent until gets to bottom of tree

                    • as it's walking down the tree and changing Instances, it's changing the corresponding DOM nodes

                • New reconciler ("fiber reconciler"):

                  • in batches (compute a little part of the tree, then come back up to see if it has other work to do)

                  • "fiber" data structure = how main thread keeps track of where it is in the tree

                    • plain JS object

                    • { stateNode, child, return, sibling, ... }

                      • 1:1 relationship with an Instance ({ stateNode })

                  • "phases"

                    • (1) Phase 1 (render / reconciliation)

                      • builds up workInProgress tree

                        • (figures out changes via this tree, but doesn't actually make the corresponding DOM node updates -- unlike the stack reconciler)

                      • can be interrupted

                    • (2) Phase 2 (commit)

                      • cannot be interrupted (all at once)

                        • (prevents UI inconsistencies -- e.g. browser deciding it needs to update)

                  • Component

                    • Set state is called (clicked button)

                    • React adds update to update queue for component

                    • React schedules the work (via requestIdleCallback)

                      • Whenever main thread has some free time (e.g. done with browser updates; no frames scheduled in the near future), it comes back to React, and start building up workInProgress tree (via workLoop function)

                        • workLoop:

                          • next unit of work

                          • time remaining (that it has with main thread)

                        • ...clone > mark as update or not (+/- need change in DOM) > create elements > ... > (shouldComponentUpdate / props / memoized?) > ... (~16-19min)

                          • ...

                          • effect list = list of changes (+ need change in DOM)

                          • ...

                          • requestIdleCallback = used when more work is to be done, but main thread needs to stay busy with browser updates

                            • browser updates = callbacks (i.e. JS event loop) (may include "layout" callback, ...)

    • Day 2

      • ...

  • React docs (old):

Last updated