/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @flow */ import type {ViewState} from './types'; import {isInternalFacebookBuild} from 'react-devtools-feature-flags'; import * as React from 'react'; import { Suspense, useContext, useDeferredValue, useLayoutEffect, useRef, useState, } from 'react'; import {SettingsContext} from 'react-devtools-shared/src/devtools/views/Settings/SettingsContext'; import {updateColorsToMatchTheme} from './content-views/constants'; import {TimelineContext} from './TimelineContext'; import ImportButton from './ImportButton'; import CanvasPage from './CanvasPage'; import {importFile} from './timelineCache'; import TimelineSearchInput from './TimelineSearchInput'; import {TimelineSearchContextController} from './TimelineSearchContext'; import styles from './Timeline.css'; export function Timeline(_: {||}) { const {file, setFile, viewState} = useContext(TimelineContext); const ref = useRef(null); // HACK: Canvas rendering uses an imperative API, // but DevTools colors are stored in CSS variables (see root.css and SettingsContext). // When the theme changes, we need to trigger update the imperative colors and re-draw the Canvas. const {theme} = useContext(SettingsContext); // HACK: SettingsContext also uses a useLayoutEffect to update styles; // make sure the theme context in SettingsContext updates before this code. const deferredTheme = useDeferredValue(theme); // HACK: Schedule a re-render of the Canvas once colors have been updated. // The easiest way to guarangee this happens is to recreate the inner Canvas component. const [key, setKey] = useState(theme); useLayoutEffect(() => { const pollForTheme = () => { if (updateColorsToMatchTheme(((ref.current: any): HTMLDivElement))) { clearInterval(intervalID); setKey(deferredTheme); } }; const intervalID = setInterval(pollForTheme, 50); return () => { clearInterval(intervalID); }; }, [deferredTheme]); return (
{file ? ( }> ) : ( )}
); } const Welcome = ({onFileSelect}: {|onFileSelect: (file: File) => void|}) => (
    {isInternalFacebookBuild && (
  1. Enable the react_enable_scheduling_profiler GK .
  2. )}
  3. Open a website that's built with the profiling build of ReactDOM (version 18 or newer).
  4. Open the "Performance" tab in Chrome and record some performance data.
  5. Click the "Save profile..." button in Chrome to export the data.
  6. Import the data into the profiler:
    Import
); const ProcessingData = () => (
Processing data...
This should only take a minute.
); const CouldNotLoadProfile = ({error, onFileSelect}) => (
Could not load profile
{error.message && (
{error.message}
)}
Try importing another Chrome performance profile.
); const FileLoader = ({ file, onFileSelect, viewState, }: {| file: File | null, onFileSelect: (file: File) => void, viewState: ViewState, |}) => { if (file === null) { return null; } const dataOrError = importFile(file); if (dataOrError instanceof Error) { return ( ); } return ( ); };