/
githubmr
/
facebook-react
Обзор
Документация
Войти
/
githubmr
/
facebook-react
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
v18.1.0
packages/react-devtools-timeline/src/Timeline.js
170 строк
5 KB
Brian Vaughn
DevTools: Timeline profiler refactor
28 янв 2022, 21:09
Не верифицирован
28 янв 2022, 21:09
fa816be
Код
Авторство
О чём код?
/** * 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 * 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 {ProfilerContext} from 'react-devtools-shared/src/devtools/views/Profiler/ProfilerContext'; import NoProfilingData from 'react-devtools-shared/src/devtools/views/Profiler/NoProfilingData'; import RecordingInProgress from 'react-devtools-shared/src/devtools/views/Profiler/RecordingInProgress'; import {updateColorsToMatchTheme} from './content-views/constants'; import {TimelineContext} from './TimelineContext'; import CanvasPage from './CanvasPage'; import {importFile} from './timelineCache'; import TimelineSearchInput from './TimelineSearchInput'; import TimelineNotSupported from './TimelineNotSupported'; import {TimelineSearchContextController} from './TimelineSearchContext'; import styles from './Timeline.css'; export function Timeline(_: {||}) { const { file, inMemoryTimelineData, isTimelineSupported, setFile, viewState, } = useContext(TimelineContext); const {didRecordCommits, isProfiling} = useContext(ProfilerContext); 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<string>(theme); useLayoutEffect(() => { const pollForTheme = () => { if (updateColorsToMatchTheme(((ref.current: any): HTMLDivElement))) { clearInterval(intervalID); setKey(deferredTheme); } }; const intervalID = setInterval(pollForTheme, 50); return () => { clearInterval(intervalID); }; }, [deferredTheme]); let content = null; if (isProfiling) { content = <RecordingInProgress />; } else if (inMemoryTimelineData && inMemoryTimelineData.length > 0) { // TODO (timeline) Support multiple renderers. const timelineData = inMemoryTimelineData[0]; content = ( <TimelineSearchContextController profilerData={timelineData} viewState={viewState}> <TimelineSearchInput /> <CanvasPage profilerData={timelineData} viewState={viewState} /> </TimelineSearchContextController> ); } else if (file) { content = ( <Suspense fallback={<ProcessingData />}> <FileLoader file={file} key={key} onFileSelect={setFile} viewState={viewState} /> </Suspense> ); } else if (didRecordCommits) { content = <NoTimelineData />; } else if (isTimelineSupported) { content = <NoProfilingData />; } else { content = <TimelineNotSupported />; } return ( <div className={styles.Content} ref={ref}> {content} </div> ); } const ProcessingData = () => ( <div className={styles.EmptyStateContainer}> <div className={styles.Header}>Processing data...</div> <div className={styles.Row}>This should only take a minute.</div> </div> ); const CouldNotLoadProfile = ({error, onFileSelect}) => ( <div className={styles.EmptyStateContainer}> <div className={styles.Header}>Could not load profile</div> {error.message && ( <div className={styles.Row}> <div className={styles.ErrorMessage}>{error.message}</div> </div> )} <div className={styles.Row}> Try importing another Chrome performance profile. </div> </div> ); const NoTimelineData = () => ( <div className={styles.EmptyStateContainer}> <div className={styles.Row}> This current profile does not contain timeline data. </div> </div> ); 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 ( <CouldNotLoadProfile error={dataOrError} onFileSelect={onFileSelect} /> ); } return ( <TimelineSearchContextController profilerData={dataOrError} viewState={viewState}> <TimelineSearchInput /> <CanvasPage profilerData={dataOrError} viewState={viewState} /> </TimelineSearchContextController> ); };