The best is yet to come: the Future of React • FULL

97d21da8e0ffa8f81218a293482c253a?s=47 Matheus
March 14, 2020

The best is yet to come: the Future of React • FULL

A wise man once said: "React is such a good idea that we will spend the rest of the decade continuing to explore its implications and applications”.

In 2017, React Fiber was the thing in the community. In 2018, hooks – and the completely new mindset they brought along – took that role with a little help of Concurrent React.

But there are a few other big things happening out there: React Fire, React Flare and the Scheduler. These go from completely rethinking the event system to bringing cooperative scheduling to the browser environment, and much more!

In this talk, we’ll look at what are these, how they fit together with other changes and, hopefully, by the end of the talk, you'll be just as enthusiastic as I am about what's coming down the line.

Last but not least, we'll take a glimpse into the future of the Web platform.

97d21da8e0ffa8f81218a293482c253a?s=128

Matheus

March 14, 2020
Tweet

Transcript

  1. THE BEST IS YET TO COME: THE FUTURE OF REACT

    Matheus Albuquerque – Software Engineer, Front-End @ STRV full
  2. 2 01 GOALS

  3. 3 contextType createRef() forwardRef() Lifecycle Changes <Strict Mode/> act() Migrating

    Stuff ReactDOM.createRoot() lazy() <Suspense/> react-cache Profiler memo() scheduler Create React App v3 GOALS • REACT RECAP
  4. 4 contextType createRef() forwardRef() Lifecycle Changes <Strict Mode/> act() Migrating

    Stuff ReactDOM.createRoot() lazy() <Suspense/> react-cache Profiler memo() scheduler Create React App v3 ALL OF THIS STARTING ON 16.3… GOALS • REACT RECAP
  5. 5 Guillermo Rauch, CEO @ZEIT “React is such a good

    idea that we will spend the rest of the decade continuing to explore its implications and applications.“
  6. 01 PRESENT A FEW THOUGHTS ON DOM, SCHEDULING AND CONTROL

    FLOW 6 6 GOALS
  7. 02 PROVE THREE THEORIES I HAVE REGARDING THE WEB PLATFORM

    AND REACT.JS 7 7 GOALS
  8. 02 PROVE THREE THEORIES I HAVE REGARDING THE WEB PLATFORM

    AND REACT.JS 8 8 GOALS no spoilers here, sorry
  9. 9 02 DISCLAIMERS

  10. 01 REACT SOURCE CODE IS NOT EASY TO READ AND

    IT IS CONSTANTLY CHANGING 10 10 DISCLAIMERS
  11. 02 SOME THOUGHTS HERE ARE SPECULATIVE 11 11 DISCLAIMERS

  12. 03 = TO0 COMPLEX; REACH ME OUT ON THE AFTERPARTY

    12 12 DISCLAIMERS
  13. 13 03 DOM

  14. REACT FIRE 14

  15. 15 Consists of… • An effort to modernize React DOM

    • Focused on making React better aligned with how the DOM works • It also aims to make React smaller and faster It brings… • Attach events at the React root rather than the document • Migrate from onChange to onInput and don’t polyfill it for uncontrolled components • className → class • React Flare • … DOM • REACT FIRE
  16. 16 • Attaching event handlers to the document becomes an

    issue when embedding React apps into larger systems • Any big application eventually faces complex edge cases related to stopPropagation interacting with non- React code or across React roots • The Atom editor was one of the first cases that bumped into this DOM • REACT FIRE • ATTACH EVENTS AT THE REACT ROOT
  17. 17 • Stop using a different event name for what's

    known as input event in the DOM • Stop polyfilling it for uncontrolled components DOM • REACT FIRE • ONCHANGE → ONINPUT
  18. REACT FLARE 18

  19. 19 • Experimental React Events API (react-events) • Necolas is

    the creator of react-native-web and cares a lot about cross-platform consistency • The Event System umbrella under React Fire DOM • REACT FLARE
  20. 20 • Make it easy to build UIs that feel

    great on desktop and mobile, with mouse and touch, and that are accessible • It includes declarative APIs for managing interactions • Unlike with the current React event system, the Flare design doesn't inflate the bundle for events you don't use • It should allow to cut down the amount of code in UI libraries that deal with mouse and touch events DOM • REACT FLARE
  21. 21 • It includes declarative APIs for managing interactions DOM

    • REACT FLARE • useTap • useKeyboard • usePress • useResponder • useFocusManager • listeners={…}
  22. 22 useKeyboard({ preventKeys: [ 'Space', [ 'Enter', { metaKey: true

    } ] 'Enter+Meta' ] }); DOM • REACT FLARE
  23. 23 const [focused, setFocusState] = useState(false); const { onBlur, onFocus

    } = useFocusManager({ onChange: nextFocused => setFocusState(nextFocused) }); return ( <div tabIndex="-1" onFocus={onFocus} onBlur={onBlur}> {String(focused)} <input /> <input /> <button>A button</button> </div> ); DOM • REACT FLARE
  24. 24 const [focused, setFocusState] = useState(false); const { onBlur, onFocus

    } = useFocusManager({ onChange: nextFocused => setFocusState(nextFocused) }); return ( <div tabIndex="-1" onFocus={onFocus} onBlur={onBlur}> {String(focused)} <input /> <input /> <button>A button</button> </div> ); DOM • REACT FLARE
  25. 25 const [focused, setFocusState] = useState(false); const { onBlur, onFocus

    } = useFocusManager({ onChange: nextFocused => setFocusState(nextFocused) }); return ( <div tabIndex="-1" onFocus={onFocus} onBlur={onBlur}> {String(focused)} <input /> <input /> <button>A button</button> </div> ); DOM • REACT FLARE
  26. 26 • The Flare event system ended up being a

    too-high-level-abstraction • As parts of the event system considered unnecessary or outdated were removed, they discovered many edge cases where it was being very helpful and prevented bugs • Reducing library code to re-add it several times in the application code was not the best tradeoff • Even basic things like buttons feel very different with mouse and touch when you use events like onClick DOM • REACT FLARE
  27. 27 DOM • REACT FLARE

  28. 28 DOM • REACT FLARE

  29. REACT.JS HAS BEEN PUSHED BY WEB APIs TO THE FUTURE

    29 29 DOM • CONCLUSIONS
  30. 30 04 SCHEDULING

  31. OVERVIEW 31

  32. 32 SCHEDULING • OVERVIEW • PROBLEMS IN UIs • Users

    expect immediate feedback • Events can happen at any time • We can’t look into the future
  33. 33 SCHEDULING • OVERVIEW

  34. 34 SCHEDULING • OVERVIEW

  35. 35 SCHEDULING • OVERVIEW

  36. 36 • Provides a scalable solution to performance • Lets

    us coordinate CPU and network-bound updates • Improves perceived performance • It doesn’t solve React.js problems; it solves UI problems SCHEDULING • OVERVIEW
  37. REACT 37

  38. 38 SCHEDULING • REACT

  39. 39 SCHEDULING • REACT Concurrent React • Allows rendering work

    to be paused and resumed later • Makes tasks smaller Scheduler • A way to schedule work in the browser • Unstable! API will change
  40. 40 SCHEDULING • REACT

  41. 41 http://bit.ly/fiber-in-depth SCHEDULING • REACT

  42. 42 SCHEDULING • REACT Immediate User Blocking Normal Low Idle

    "Do it now" Now! "Do it now" 250ms "Do it soon" 5s "Do it eventually” 10s "Do it if you can” No timeout
  43. 43 SCHEDULING • REACT Immediate User Blocking Normal Low Idle

    "Do it now" Now! "Do it now" 250ms "Do it soon" 5s "Do it eventually” 10s "Do it if you can” No timeout first one is really sync
  44. 44 SCHEDULING • REACT

  45. 45 SCHEDULING • REACT • DEMO

  46. 46 SCHEDULING • REACT • DEMO

  47. 47 ReactDOM.render( CONCURRENT_AND_SCHEDULED ? ( <React.unstable_ConcurrentMode> <App /> </React.unstable_ConcurrentMode> )

    : ( <App /> ), rootElement ); SCHEDULING • REACT • DEMO
  48. 48 ReactDOM.render( CONCURRENT_AND_SCHEDULED ? ( <React.unstable_ConcurrentMode> <App /> </React.unstable_ConcurrentMode> )

    : ( <App /> ), rootElement ); SCHEDULING • REACT • DEMO Enabling the unstable Concurrent Mode
  49. 49 const handleChange = useCallback(event => { const value =

    event.target.value; if (CONCURRENT_AND_SCHEDULED) { setInputValue(value); unstable_next(function() { onChange(value); }); sendDeferredPing(value); } else { setInputValue(value); onChange(value); sendPing(value); } }); SCHEDULING • REACT • DEMO
  50. 50 const handleChange = useCallback(event => { const value =

    event.target.value; if (CONCURRENT_AND_SCHEDULED) { setInputValue(value); unstable_next(function() { onChange(value); }); sendDeferredPing(value); } else { setInputValue(value); onChange(value); sendPing(value); } }); SCHEDULING • REACT • DEMO Queue a task with a lower priority than the default priority of interaction callbacks.
  51. 51 const handleChange = useCallback(event => { const value =

    event.target.value; if (CONCURRENT_AND_SCHEDULED) { setInputValue(value); unstable_next(function() { onChange(value); }); sendDeferredPing(value); } else { setInputValue(value); onChange(value); sendPing(value); } }); SCHEDULING • REACT • DEMO
  52. 52 const handleChange = useCallback(event => { const value =

    event.target.value; if (CONCURRENT_AND_SCHEDULED) { setInputValue(value); unstable_next(function() { onChange(value); }); sendDeferredPing(value); } else { setInputValue(value); onChange(value); sendPing(value); } }); SCHEDULING • REACT • DEMO
  53. 53 const sendPing = value => { performance.mark("analytics-start"); someRandomOperation(25); performance.mark("analytics-end");

    performance.measure( "Analytics: " + value, "analytics-start", "analytics-end" ); }; const sendDeferredPing = value => { unstable_scheduleCallback(unstable_LowPriority, function() { sendPing(value); }); }; SCHEDULING • REACT • DEMO
  54. 54 const sendPing = value => { performance.mark("analytics-start"); someRandomOperation(25); performance.mark("analytics-end");

    performance.measure( "Analytics: " + value, "analytics-start", "analytics-end" ); }; const sendDeferredPing = value => { unstable_scheduleCallback(unstable_LowPriority, function() { sendPing(value); }); }; SCHEDULING • REACT • DEMO We can schedule a callback with an even lower priority.
  55. 55 SCHEDULING • REACT • DEMO

  56. 56 SCHEDULING • REACT • DEMO

  57. 57 SCHEDULING • REACT • DEMO Demo recap • Concurrent

    React can break long running tasks into chunks • The scheduler allows us to prioritize important updates
  58. THE WEB 58

  59. 59 SCHEDULING • THE WEB • Everyone should use the

    same scheduler • Having more than one scheduler causes resource fighting • Interleaving tasks with browser work (rendering, GC)
  60. 60 SCHEDULING • THE WEB We have a few scheduling

    primitives: • setTimeout • requestAnimationFrame • requestIdleCallback • postMessage
  61. WE NEED SCHEDULING PRIMITIVES 61 61 SCHEDULING • THE WEB

  62. 62 SCHEDULING • THE WEB

  63. 63 SCHEDULING • THE WEB https://github.com/WICG/main-thread-scheduling

  64. 64 SCHEDULING • THE WEB • Developed in cooperation with

    React, Polymer, Ember, Google Maps, and the Web Standards Community • Aligned with the work of the React Core Team • Integrated directly into the event loop
  65. 65 SCHEDULING • THE WEB

  66. 66 SCHEDULING • THE WEB https://engineering.fb.com/developer-tools/isinputpending-api/

  67. 67 SCHEDULING • THE WEB

  68. 68 SCHEDULING • THE WEB https://wicg.github.io/is-input-pending

  69. 69 while (workQueue.length > 0) { if (navigator.scheduling.isInputPending()) { //

    Stop doing work if we have to handle an input event. break; } let job = workQueue.shift(); job.execute(); } SCHEDULING • THE WEB
  70. 70 while (workQueue.length > 0) { if (navigator.scheduling.isInputPending(['mousedown', 'keydown'])) {

    // Stop doing work if we think we'll start receiving a mouse or key event. break; } let job = workQueue.shift(); job.execute(); } SCHEDULING • THE WEB
  71. 71 SCHEDULING • CONCLUSIONS • Scheduling is necessary for responsive

    user interfaces • We can solve a lot at the framework level with Concurrent React and the Scheduler • A Web Standards proposal is in making that brins a scheduler API to the browser
  72. REACT.JS HAS BEEN PUSHING WEB APIs TO THE FUTURE 72

    72 SCHEDULING • CONCLUSIONS
  73. 73 05 CONTROL FLOW

  74. EFFECT HANDLERS 74

  75. 75 $$$ CONTROL FLOW • EFFECT HANDLERS

  76. 76 CONTROL FLOW • EFFECT HANDLERS

  77. 77 CONTROL FLOW • EFFECT HANDLERS https://overreacted.io/algebraic-effects-for-the-rest-of-us

  78. 78 CONTROL FLOW • EFFECT HANDLERS function getName(user) { let

    name = user.name; if (name === null) { name = perform 'ask_name'; } return name; } const arya = { name: null, friendNames: [] }; const gendry = { name: 'Gendry', friendNames: [] }; try { getName(arya); } handle (effect) { if (effect === 'ask_name') { resume with 'Arya Stark'; } }
  79. 79 CONTROL FLOW • EFFECT HANDLERS function getName(user) { let

    name = user.name; if (name === null) { name = perform 'ask_name'; } return name; } const arya = { name: null, friendNames: [] }; const gendry = { name: 'Gendry', friendNames: [] }; try { getName(arya); } handle (effect) { if (effect === 'ask_name') { resume with 'Arya Stark'; } } throw ↝ perform catch ↝ handle lets us jump back to where we performed the effect
  80. 80 CONTROL FLOW • EFFECT HANDLERS

  81. 81 CONTROL FLOW • EFFECT HANDLERS https://github.com/macabeus/js-proposal-algebraic-effects

  82. REACT 82

  83. 83 CONTROL FLOW • REACT

  84. 84 CONTROL FLOW • REACT

  85. 85 https://esdiscuss.org/topic/one-shot-delimited-continuations-with-effect-handlers CONTROL FLOW • REACT

  86. 86 CONTROL FLOW • REACT

  87. 87 CONTROL FLOW • REACT The React team apparently spent

    some time experimenting with using effect-handler control structures for managing layout
  88. 88 CONTROL FLOW • REACT

  89. 89 CONTROL FLOW • REACT …and also for implementing the

    context API.
  90. 90 CONTROL FLOW • REACT

  91. 91 CONTROL FLOW • REACT Sebastian points that “conceptually, they

    [hooks] are algebraic effects”.
  92. 92 $$$ CONTROL FLOW • REACT

  93. 93 CONTROL FLOW • REACT

  94. 94 CONTROL FLOW • REACT A component is able to

    suspend the fiber it is running in by throwing a promise, which is caught and handled by the framework.
  95. 95 CONTROL FLOW • REACT A component is able to

    suspend the fiber it is running in by throwing a promise, which is caught and handled by the framework. throw-handle-resume pattern
  96. 96 2016 2016 2017 2018 2019 Effect Handlers as ECMAScript

    proposal CONTROL FLOW • REACT Effect Handlers experiments (Layout) Effect Handlers experiments (Context) Effect Handlers as Hooks Effect Handlers as Suspense
  97. REACT.JS HAS BEEN PUSHING WEB APIs TO THE FUTURE 97

    97 CONTROL FLOW • CONCLUSIONS
  98. 98 06 OTHER COOL STUFF

  99. TRUSTED TYPES 99

  100. 100 OTHER COOL STUFF • TRUSTED TYPES

  101. 101 https://developers.google.com/web/updates/2019/02/trusted-types OTHER COOL STUFF • TRUSTED TYPES

  102. 102 • Help obliterate DOM XSS • Allow you to

    lock down the dangerous injection sinks OTHER COOL STUFF • TRUSTED TYPES
  103. 103 OTHER COOL STUFF • TRUSTED TYPES

  104. 104 OTHER COOL STUFF • TRUSTED TYPES

  105. FAST REFRESH 105

  106. 106 • It's a reimplementation of hot reloading with full

    support from React • It's originally shipping for React Native but most of the implementation is platform-independent • The plan is to use it across the board — as a replacement for purely userland solutions (like react-hot-loader) • Adoption requires integration with existing bundlers common on the web (e.g. Webpack, Parcel etc.) OTHER COOL STUFF • FAST REFRESH
  107. 107 OTHER COOL STUFF • FAST REFRESH

  108. REACT FRESH 108

  109. 109 • A new generation of hot reloading • Changes

    include initial scaffolding, infrastructure, and Babel plugin implementation OTHER COOL STUFF • REACT FRESH
  110. 110 OTHER COOL STUFF • REACT FRESH

  111. 111 OTHER COOL STUFF • REACT FRESH

  112. 112 OTHER COOL STUFF • REACT FRESH Z

  113. 113 OTHER COOL STUFF • REACT FRESH Z

  114. REACT FLIGHT 114

  115. 115 • ”An experimental API aimed to greatly improve server

    side rendering experience” – Philipp Spiess • ”A non-GraphQL solution for composing arbitrary data logic in a parallel hierarchy to your components” – Dan Abramov • Probably somehow related to mapping URLs to data and views (similar to Navi) OTHER COOL STUFF • REACT FLIGHT
  116. 116 Z OTHER COOL STUFF • REACT FLIGHT

  117. 117 Z OTHER COOL STUFF • REACT FLIGHT

  118. 118 OTHER COOL STUFF • REACT FLIGHT

  119. 119 07 CONCLUSIONS

  120. 120 $$$ CONCLUSIONS • THEORIES

  121. 121 CONCLUSIONS • THEORIES

  122. 122 CONCLUSIONS • THEORIES

  123. 123 CONCLUSIONS • THEORIES

  124. 01 REACT.JS HAS BEEN PUSHING OTHER ECOSYSTEMS TO THE FUTURE

    124 124 e.g. Swift UI and other declarative-UIs efforts CONCLUSIONS • THEORIES
  125. 02 REACT.JS HAS BEEN PUSHING WEB APIs TO THE FUTURE

    125 125 e.g. Scheduler API, Fast Refresh, React Fresh, Trusted Types & Effect Handlers CONCLUSIONS • THEORIES
  126. REACT.JS HAS BEEN PUSHED BY WEB APIs TO THE FUTURE

    126 126 e.g. React Fire and React Flare, Trusted Types 03 CONCLUSIONS • THEORIES
  127. 127 Guillermo Rauch, CEO @ZEIT “React is such a good

    idea that we will spend the rest of the decade continuing to explore its implications and applications.“
  128. THE BEST IS YET TO COME THE FUTURE OF REACT

    Matheus Albuquerque – Software Engineer, Front-End @ STRV
  129. THE BEST IS YET TO COME THE FUTURE OF REACT

    Matheus Albuquerque – Software Engineer, Front-End @ STRV IS
  130. ONE MORE THING 130 130 CONCLUSIONS • THE FUTURE

  131. 131 CONCLUSIONS • THE FUTURE

  132. 132 Walking this whole tree… …just to update this value

    CONCLUSIONS • THE FUTURE
  133. 133 133 CONCLUSIONS • THE FUTURE

  134. 134 shouldComponentUpdate() PureComponent useMemo() useCallback() memo Concurrent React CONCLUSIONS •

    THE FUTURE
  135. 135 shouldComponentUpdate() PureComponent useMemo() useCallback() memo Concurrent React AMORTIZATIONS FOR

    A CRUCIAL PERF ISSUE CONCLUSIONS • THE FUTURE
  136. 136 CONCLUSIONS • THE FUTURE

  137. 137 Languages for describing reactive user interfaces. CONCLUSIONS • THE

    FUTURE
  138. THE BEST IS YET TO COME THE FUTURE OF REACT

    Matheus Albuquerque – Software Engineer, Front-End @ STRV IS
  139. THE BEST IS YET TO COME THE FUTURE OF REACT

    Matheus Albuquerque – Software Engineer, Front-End @ STRV IS NOT
  140. 140 140 CONCLUSIONS • THE PAST

  141. 141 141 This is me giving a talk about Ionic

    on an iOS developers meetup five years ago telling them that Angular would be the future. CONCLUSIONS • THE PAST
  142. 142 142 This is me giving a talk about Ionic

    on an iOS developers meetup five years ago telling them that Angular would be the future. CONCLUSIONS • THE PAST
  143. 143 143 This is me giving a talk about Ionic

    on an iOS developers meetup five years ago telling them that Angular would be the future. CONCLUSIONS • THE PAST
  144. 144 144 This is me giving a talk about Ionic

    on an iOS developers meetup five years ago telling them that Angular would be the future. CONCLUSIONS • THE PAST
  145. 04 DON’T TRUST MY FUTURE PREDICTIONS 145 145 CONCLUSIONS •

    THE PAST
  146. 146 08 THIS TALK

  147. 147 THIS TALK • KEYNOTE

  148. 148 THIS TALK • KEYNOTE https://speakerdeck.com/ythecombinator

  149. 149 MATHEUS ALBUQUERQUE @ythecombinator www.ythecombinator.space land@ythecombinator.space

  150. 150 THIS TALK • STICKERS

  151. 151 THIS TALK • STICKERS I GOT STICKERS!

  152. Matheus Albuquerque – Software Engineer, Front-End @ STRV FORTE ABRAÇO