diff --git a/src/devtools/views/DevTools.js b/src/devtools/views/DevTools.js
index d2d9cb8474..3473582f04 100644
--- a/src/devtools/views/DevTools.js
+++ b/src/devtools/views/DevTools.js
@@ -9,6 +9,7 @@ import Settings from './Settings/Settings';
import TabBar from './TabBar';
import { SettingsContextController } from './Settings/SettingsContext';
import { TreeContextController } from './Elements/TreeContext';
+import { ProfilerContextController } from './Profiler/ProfilerContext';
import ReactLogo from './ReactLogo';
import styles from './DevTools.css';
@@ -104,27 +105,31 @@ export default function DevTools({
-
- {showTabBar && (
-
-
-
- {process.env.DEVTOOLS_VERSION}
-
-
-
-
- )}
-
{tabElement}
-
+
+
+ {showTabBar && (
+
+
+
+ {process.env.DEVTOOLS_VERSION}
+
+
+
+
+ )}
+
{tabElement}
+
+
diff --git a/src/devtools/views/Profiler/FilterModal.js b/src/devtools/views/Profiler/FilterModal.js
index 085fee0a7f..363919c08f 100644
--- a/src/devtools/views/Profiler/FilterModal.js
+++ b/src/devtools/views/Profiler/FilterModal.js
@@ -1,7 +1,8 @@
// @flow
-import React, { useCallback, useEffect, useRef } from 'react';
-import { useLocalStorage, useModalDismissSignal } from '../hooks';
+import React, { useCallback, useContext, useEffect, useRef } from 'react';
+import { ProfilerContext } from './ProfilerContext';
+import { useModalDismissSignal } from '../hooks';
import styles from './FilterModal.css';
@@ -10,14 +11,12 @@ type Props = {|
|};
export default function FilterModal({ dismissModal }: Props) {
- const [
+ const {
isCommitFilterEnabled,
+ minCommitDuration,
setIsCommitFilterEnabled,
- ] = useLocalStorage('isCommitFilterEnabled', false);
- const [minCommitDuration, setMinCommitDuration] = useLocalStorage(
- 'minCommitDuration',
- 0
- );
+ setMinCommitDuration,
+ } = useContext(ProfilerContext);
const handleNumberChange = useCallback(
({ currentTarget }) => {
diff --git a/src/devtools/views/Profiler/Profiler.js b/src/devtools/views/Profiler/Profiler.js
index 2e835066b5..0a647919e9 100644
--- a/src/devtools/views/Profiler/Profiler.js
+++ b/src/devtools/views/Profiler/Profiler.js
@@ -1,11 +1,7 @@
// @flow
import React, { Suspense, useCallback, useContext, useState } from 'react';
-import { ProfilerDataContextController } from './ProfilerDataContext';
-import {
- ProfilerStatusContext,
- ProfilerStatusContextController,
-} from './ProfilerStatusContext';
+import { ProfilerContext } from './ProfilerContext';
import Button from '../Button';
import ButtonIcon from '../ButtonIcon';
import TabBar from '../TabBar';
@@ -15,46 +11,68 @@ import SnapshotSelector from './SnapshotSelector';
import styles from './Profiler.css';
-export type Props = {||};
+export default function Profiler(_: {||}) {
+ const { hasProfilingData, isProfiling } = useContext(ProfilerContext);
-export default function ProfilerOuter(_: Props) {
- return (
-
+ if (isProfiling || !hasProfilingData) {
+ return ;
+ } else {
+ return (
}>
-
-
-
+
-
+ );
+ }
+}
+
+// This view is rendered when there is no profiler data (either we haven't profiled yet or we're currently profiling).
+// Nothing in this view's subtree suspends.
+// By not suspending while profiling is in progress, we avoid potential cache invalidation trickiness.
+function NonSuspendingProfiler({ isProfiling }: {| isProfiling: boolean |}) {
+ const view = isProfiling ? : ;
+
+ return (
+
+
+
+
+
+
+ {}}
+ size="small"
+ tabs={tabs}
+ />
+
+
{view}
+
+
);
}
+// TODO (profiling) Real fallback UI
function ProfilerFallback() {
- // TODO (profiling) Real fallback UI
- return null;
+ return
Loading...
;
}
-function ProfilerInner(_: Props) {
- const { hasProfilingData, isProfiling } = useContext(ProfilerStatusContext);
-
- const showProfilingControls = !isProfiling && hasProfilingData;
-
+// This view is rendered when there is profiler data (even though there may not be any for the currently selected root).
+// This view's subtree uses suspense to request profiler data from the backend.
+function SuspendingProfiler(_: {||}) {
const [tab, setTab] = useState('flame-chart');
const [isFilterModalShowing, setIsFilterModalShowing] = useState(false);
const showFilterModal = useCallback(() => setIsFilterModalShowing(true));
const dismissFilterModal = useCallback(() => setIsFilterModalShowing(false));
- let view = null;
- if (isProfiling) {
- view = ;
- } else if (!hasProfilingData) {
- view = ;
- } else {
- // TODO (profiling) Differentiate between no data and no data for the current root
- // TODO (profiling) Show selected "tab" view
- view =
Coming soon...
;
- }
+ // TODO (profiling) Differentiate between no data and no data for the current root
+ // TODO (profiling) Show selected "tab" view
+ const view =