1 of 28

Slow to Fast: Looking at React Performance Problems

Abhijeet Prasad

Software Engineer at Sentry (sentry.io)

2 of 28

Agenda 📓

  1. User Operations�
  2. Components
    1. Building and optimizing components
    2. Browser Dev Tools
    3. React Profiler API�
  3. Pages
    • Building and optimizing pages
    • Browser APIs + Metrics

3 of 28

How do your users use your web application? 🤔

4 of 28

What are the operations we care about?

Page rendering

  • Pageload
  • Route changes (navigation)

User interactions

  • Keyboard/Mouse
  • Forms
  • Animations

5 of 28

An example with Sentry

Issue Details

Editing Dashboards

6 of 28

A React component

7 of 28

Under the hood

  • Rendering
    • Virtual DOM: data structure representation of a UI
    • Rendering elements with React.createElement: <App />
  • Reconciliation (pre-commit)
    • Virtual DOM diffing�
  • Committing Updates
    • Manipulating data is often not expensive, but DOM layout I/O is

8 of 28

Goal: Minimize commits

9 of 28

Well, how can you tell?

  • console.log
    • shouldComponentUpdate
  • React Dev Tools
    • Component View
    • Profiler View�
  • Browser Dev Tools

10 of 28

Visualizing component re-renders

11 of 28

React component flamegraph

12 of 28

Browser Dev Tools

13 of 28

Digging deep into components

  • React profiling bundle + React Profiler API�
  • Larger variety of user conditions

14 of 28

Using the React Profiler API

  • Track the timings you care about!

15 of 28

Using the Profiler at Sentry

16 of 28

Using the Profiler at Sentry

17 of 28

Common problems

  • Frequent state updates on event listeners (e.g., scroll, drag, keydown)�
  • Many, many, many components on a screen at the same time�
  • React Context�
  • Expensive computations blocking the main thread�
  • Serial Network Requests

18 of 28

Fixing the problematic component! 🎯

  • Measure first!
  • Memoization
    • React.PureComponent, React.memo
    • useMemo, useCallback
  • Bundle Optimization
    • Lazy loading�
  • Virtualization

19 of 28

Memoizing props

  • Use React.memo to skip rendering if passed the same props�
  • Can also provide a more detail matcher for more finely grained control�
  • Remember not to overuse! If you can’t see the impact, don’t use it

20 of 28

Memoizing computations

  • Use useMemo to avoid expensive computations every render
    • Easier to control when individual children update�
  • Use useCallback to keep the same callback references on every render�

21 of 28

Lazy loading

  • Reduce code needed during initial load�

22 of 28

Virtualization

  • Render only what can be seen in the current viewport
    • Common with lists and tables�
  • Recommend https://github.com/bvaughn/react-window
  • You can also roll your own setup

23 of 28

Components -> Pages

  • Sometimes you can only do so much analyzing a component/set of components�
  • Complex: many pages, and many page states

Sentry Release Page

24 of 28

Start measuring in the field!

  • Web Vitals
  • React Profiler API�
  • PerformanceObserver API�

25 of 28

Use field data to figure out where to profile further

26 of 28

Install Sentry!

27 of 28

Sentry Performance Monitoring

28 of 28

Thank you