Open
Description
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
- Requires “debugger” permission, but it should be an optional permission that we just-in-time prompt for.
- (ʀᴇᴀᴄᴛ/ᴅᴇᴠᴛᴏᴏʟ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.
- When user starts profiling React, Chrome’s profiling recorder should also be started.
- (ʀᴇᴀᴄᴛ/ᴅᴇᴠᴛᴏᴏʟ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.