/
githubmr
/
facebook-react
Обзор
Документация
Войти
/
githubmr
/
facebook-react
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
v17.0.2
packages/react-devtools-scheduling-profiler/src/SchedulingProfiler.js
145 строк
4 KB
E-Liang Tan
Scheduling Profiler: Move preprocessing to web worker and add loading indicator (#19759)
04 сен 2020, 17:57
Не верифицирован
04 сен 2020, 17:57
eabd18c
Код
Авторство
О чём код?
/** * 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 {Resource} from 'react-devtools-shared/src/devtools/cache'; import type {ReactProfilerData} from './types'; import type {ImportWorkerOutputData} from './import-worker/import.worker'; import * as React from 'react'; import {Suspense, useCallback, useState} from 'react'; import {createResource} from 'react-devtools-shared/src/devtools/cache'; import ReactLogo from 'react-devtools-shared/src/devtools/views/ReactLogo'; import ImportButton from './ImportButton'; import CanvasPage from './CanvasPage'; import ImportWorker from './import-worker/import.worker'; import profilerBrowser from './assets/profilerBrowser.png'; import styles from './SchedulingProfiler.css'; type DataResource = Resource<void, File, ReactProfilerData | Error>; function createDataResourceFromImportedFile(file: File): DataResource { return createResource( () => { return new Promise<ReactProfilerData | Error>((resolve, reject) => { const worker: Worker = new (ImportWorker: any)(); worker.onmessage = function(event) { const data = ((event.data: any): ImportWorkerOutputData); switch (data.status) { case 'SUCCESS': resolve(data.processedData); break; case 'INVALID_PROFILE_ERROR': resolve(data.error); break; case 'UNEXPECTED_ERROR': reject(data.error); break; } worker.terminate(); }; worker.postMessage({file}); }); }, () => file, {useWeakMap: true}, ); } export function SchedulingProfiler(_: {||}) { const [dataResource, setDataResource] = useState<DataResource | null>(null); const handleFileSelect = useCallback((file: File) => { setDataResource(createDataResourceFromImportedFile(file)); }, []); return ( <div className={styles.SchedulingProfiler}> <div className={styles.Toolbar}> <ReactLogo /> <span className={styles.AppName}>Concurrent Mode Profiler</span> <div className={styles.VRule} /> <ImportButton onFileSelect={handleFileSelect} /> <div className={styles.Spacer} /> </div> <div className={styles.Content}> {dataResource ? ( <Suspense fallback={<ProcessingData />}> <DataResourceComponent dataResource={dataResource} onFileSelect={handleFileSelect} /> </Suspense> ) : ( <Welcome onFileSelect={handleFileSelect} /> )} </div> </div> ); } const Welcome = ({onFileSelect}: {|onFileSelect: (file: File) => void|}) => ( <div className={styles.EmptyStateContainer}> <div className={styles.ScreenshotWrapper}> <img src={profilerBrowser} className={styles.Screenshot} alt="Profiler screenshot" /> </div> <div className={styles.Header}>Welcome!</div> <div className={styles.Row}> Click the import button <ImportButton onFileSelect={onFileSelect} /> to import a Chrome performance profile. </div> </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 <ImportButton onFileSelect={onFileSelect} /> another Chrome performance profile. </div> </div> ); const DataResourceComponent = ({ dataResource, onFileSelect, }: {| dataResource: DataResource, onFileSelect: (file: File) => void, |}) => { const dataOrError = dataResource.read(); if (dataOrError instanceof Error) { return ( <CouldNotLoadProfile error={dataOrError} onFileSelect={onFileSelect} /> ); } return <CanvasPage profilerData={dataOrError} />; };