Import React Concurrent Mode Profiler (#19634) Co-authored-by: Brian Vaughn <bvaughn@fb.com> Co-authored-by: Kartik Choudhary <kartikc.918@gmail.com> - #7
Conversation
Co-authored-by: Brian Vaughn <bvaughn@fb.com> Co-authored-by: Kartik Choudhary <kartikc.918@gmail.com>
There was a problem hiding this comment.
Pull request overview
This PR imports a React Concurrent Mode Profiler, a comprehensive tool for visualizing and analyzing React performance data from Chrome DevTools timelines. The profiler provides visualization of React's scheduling, rendering, commits, and other lifecycle events.
Key Changes:
- Adds new
react-devtools-scheduling-profilerpackage with complete profiling visualization capabilities - Integrates speedscope for flamechart visualization
- Implements custom canvas-based view system for performance visualization
- Adds multiple dependencies including webpack loaders, babel, and React packages
Reviewed changes
Copilot reviewed 53 out of 58 changed files in this pull request and generated 13 comments.
Show a summary per file
| File | Description |
|---|---|
| yarn.lock | Adds numerous new dependencies for the profiler including webpack loaders, babel plugins, type definitions, and the @elg/speedscope package |
| webpack.config.js | Complete webpack configuration for building the profiler with babel, CSS modules, and file loaders |
| src/view-base/* | Custom canvas-based view system for rendering profiler UI with geometry utilities, layout system, and interaction handling |
| src/utils/* | Utility functions for data preprocessing, file reading, and UI helpers |
| src/types.js | Flow type definitions for profiler data structures |
| src/context/* | Context menu implementation for the profiler UI |
| src/content-views/* | Visualization components for different profiler data types |
| src/index.js | Application entry point using React's unstable_createRoot |
| CSS files | Styling for profiler UI components |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if (element !== null) { | ||
| if (pageY + element.offsetHeight >= ownerWindow.innerHeight) { | ||
| if (pageY - element.offsetHeight > 0) { | ||
| element.style.top = `${pageY - element.offsetHeight}px`; | ||
| } else { | ||
| element.style.top = '0px'; | ||
| } | ||
| } else { | ||
| element.style.top = `${pageY}px`; | ||
| } | ||
|
|
||
| if (pageX + element.offsetWidth >= ownerWindow.innerWidth) { | ||
| if (pageX - element.offsetWidth > 0) { | ||
| element.style.left = `${pageX - element.offsetWidth}px`; | ||
| } else { | ||
| element.style.left = '0px'; | ||
| } | ||
| } else { | ||
| element.style.left = `${pageX}px`; | ||
| } |
There was a problem hiding this comment.
This guard always evaluates to true.
| if (element !== null) { | |
| if (pageY + element.offsetHeight >= ownerWindow.innerHeight) { | |
| if (pageY - element.offsetHeight > 0) { | |
| element.style.top = `${pageY - element.offsetHeight}px`; | |
| } else { | |
| element.style.top = '0px'; | |
| } | |
| } else { | |
| element.style.top = `${pageY}px`; | |
| } | |
| if (pageX + element.offsetWidth >= ownerWindow.innerWidth) { | |
| if (pageX - element.offsetWidth > 0) { | |
| element.style.left = `${pageX - element.offsetWidth}px`; | |
| } else { | |
| element.style.left = '0px'; | |
| } | |
| } else { | |
| element.style.left = `${pageX}px`; | |
| } | |
| if (pageY + element.offsetHeight >= ownerWindow.innerHeight) { | |
| if (pageY - element.offsetHeight > 0) { | |
| element.style.top = `${pageY - element.offsetHeight}px`; | |
| } else { | |
| element.style.top = '0px'; | |
| } | |
| } else { | |
| element.style.top = `${pageY}px`; | |
| } | |
| if (pageX + element.offsetWidth >= ownerWindow.innerWidth) { | |
| if (pageX - element.offsetWidth > 0) { | |
| element.style.left = `${pageX - element.offsetWidth}px`; | |
| } else { | |
| element.style.left = '0px'; | |
| } | |
| } else { | |
| element.style.left = `${pageX}px`; |
| } from './types'; | ||
|
|
||
| import * as React from 'react'; | ||
| import {Fragment, useRef} from 'react'; |
There was a problem hiding this comment.
Unused import useRef.
| import {Fragment, useRef} from 'react'; | |
| import {Fragment} from 'react'; |
| import { | ||
| ColorView, | ||
| Surface, | ||
| View, | ||
| layeredLayout, | ||
| rectContainsPoint, | ||
| rectEqualToRect, | ||
| intersectionOfRects, | ||
| rectIntersectsRect, | ||
| verticallyStackedLayout, | ||
| } from '../view-base'; |
There was a problem hiding this comment.
Unused import Surface.
| import { | ||
| View, | ||
| Surface, | ||
| rectContainsPoint, | ||
| rectIntersectsRect, | ||
| intersectionOfRects, | ||
| } from '../view-base'; |
There was a problem hiding this comment.
Unused import Surface.
| import { | ||
| View, | ||
| Surface, | ||
| rectContainsPoint, | ||
| rectIntersectsRect, | ||
| intersectionOfRects, | ||
| } from '../view-base'; |
There was a problem hiding this comment.
Unused import Surface.
| } from './useCanvasInteraction'; | ||
| import type {Rect} from './geometry'; | ||
|
|
||
| import {Surface} from './Surface'; |
There was a problem hiding this comment.
Unused import Surface.
| import type {Rect, Size} from './geometry'; | ||
|
|
||
| import nullthrows from 'nullthrows'; | ||
| import {Surface} from './Surface'; |
There was a problem hiding this comment.
Unused import Surface.
|
|
||
| import memoize from 'memoize-one'; | ||
|
|
||
| import {View} from './View'; |
There was a problem hiding this comment.
Unused import View.
| } from './useCanvasInteraction'; | ||
| import type {Rect} from './geometry'; | ||
|
|
||
| import {Surface} from './Surface'; |
There was a problem hiding this comment.
Unused import Surface.
| import type {Rect, Size} from './geometry'; | ||
| import type {Layouter} from './layouter'; | ||
|
|
||
| import {Surface} from './Surface'; |
There was a problem hiding this comment.
Unused import Surface.
No description provided.