Skip to content

Root-level performance events #15727

Open
@bvaughn

Description

@bvaughn

DevTools (and other perf related infra) would benefit from being able to observer the following:

  • Starting (or resuming) work on a root.
  • Completing (or yielding) work on a root.
  • Committing work for a root.
  • A particularly component suspending during a render.
  • A suspended (identified by a component stack) promise resolving/retrying.
  • An update being scheduled (e.g. setState) by a component (identified by a component stack).
  • A root-level render call being made.

In order to fit within the context of the scheduler, we would also want to emit/capture the following events:

  • The scheduler is starting to run tasks at a specific priority.
  • The scheduler is stopping.
  • The scheduler currently has X number of tasks scheduled for each priority. (Maybe this could be logged periodically? Or along with each time we stopped work at a priority?)

We could use this info to e.g. draw a timeline in the Profiler UI that showed CPU/IO work breakdown.

If we used a mechanism like performance.mark to record these events as part of the browser's profiling session, we could also include information about unscheduled JavaScript- as well as other important related concepts, like network requests, paints, etc.

Sequencing

  • (ʀᴇᴀᴄᴛ) Add logging to react-reconciler and scheduler packages.
    • e.g. Make sure we are logging start/stop/yield/cancel for renders correctly
    • e.g. Make sure state-updates are being logged with the scheduled priority (not just the current)
    • Research: Make sure performance.mark is actually fast enough to use.
    • Add some basic test coverage to ensure we are marking the expected events in the expected order.
    • (Do not expose component stacks for now).
  • (ʀᴇᴀᴄᴛ) Design API for DevTools to start/stop performance marking.
    • This shouldn’t be on by default, only when we’re actually profiling.
  • (ʀᴇᴀᴄᴛ) Design public API (if we want one) for collecting and logging these new data points.
    • Web-speed would probably like to collect this data.
  • (ᴅᴇᴠᴛᴏᴏʟs) Parse Chrome performance profile JSON output.
    • Filter unsupported event types.
    • Massage data slightly (e.g. combine multiple micro-yields into a single task).
  • (ᴅᴇᴠᴛᴏᴏʟs) Create visualization (chart) UI for data.
    • Turn individual events (or “B” and “E” pairs) into graphics on a timeline.
    • Needs exploratory prototyping / design work.
  • (ᴅᴇᴠᴛᴏᴏʟs) Create zoom-and-pan controls.
    • Something that works similar to Chrome’s Performance tab probably.
    • Enables zooming in on regions of profiling data.
    • Would be nice to build using the interactions stuff Dominic/Nicolas made for Comet
    • Consider not zooming all the way out by default (but setting some max zoom-out cap?)
    • Consider adding windowing logic to avoid rendering things outside of the viewport?
  • (ᴅᴇᴠᴛᴏᴏʟs) Add Chrome debug protocol support
  • (ʀᴇᴀᴄᴛ/ᴅᴇᴠᴛᴏᴏʟs) Initial integration.
    • When user starts profiling React, Chrome’s profiling recorder should also be started.
      • We may want to enable running one without the other? Depends on how much overhead.
    • Also call the React hook to enable performance.mark calls for scheduler and react-dom.
  • (ʀᴇᴀᴄᴛ/ᴅᴇᴠᴛᴏᴏʟs) Improved integration.
    • Add component stack ID to marked “update state” and “suspend” events (e.g. “state-update-normal-123”)
    • Read actual component stack string from DevTools using this ID.
  • (ʀᴇᴀᴄᴛ/ᴅᴇᴠᴛᴏᴏʟs) Explore implementing a queue size visualization
    • Would require a new event or a hook into scheduler to get the current queue size.

Metadata

Metadata

Labels

React Core TeamOpened by a member of the React Core Team

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions