diff --git a/src/components/page-react-timings/App.tsx b/src/components/page-react-timings/App.tsx
index ba5eaaa..42c1e8a 100644
--- a/src/components/page-react-timings/App.tsx
+++ b/src/components/page-react-timings/App.tsx
@@ -1,4 +1,5 @@
import React from "react";
+import { log } from "./tasks";
const getRandomColor = () => {
return `lch(${Math.floor(Math.random() * 20) + 50}% ${
@@ -19,60 +20,10 @@ declare global {
};
}
-const TimingContext = React.createContext(false);
-
-function measureTiming(label: string, color: string, withTiming: boolean) {
- if (withTiming) {
- console.log(performance.now().toFixed(1) + "ms " + label, color);
- queueMicrotask(function measureTiming_microTask() {
- console.log(
- performance.now().toFixed(1) + "ms microtask " + label,
- color
- );
- });
- requestAnimationFrame(function measureTiming_requestAnimationFrame() {
- console.log(
- performance.now().toFixed(1) + "ms requestAnimationFrame " + label,
- color
- );
- });
- scheduler.postTask(
- function measureTiming_userBlockingTask() {
- console.log(
- performance.now().toFixed(1) + "ms user-blocking task " + label,
- color
- );
- },
- {
- priority: "user-blocking",
- }
- );
- scheduler.postTask(
- function measureTiming_userVisibleTask() {
- console.log(
- performance.now().toFixed(1) + "ms user-visible task " + label,
- color
- );
- },
- {
- priority: "user-visible",
- }
- );
- scheduler.postTask(
- function measureTiming_backgroundTask() {
- console.log(
- performance.now().toFixed(1) + "ms background task " + label,
- color
- );
- },
- {
- priority: "background",
- }
- );
- } else {
- console.log(label, color);
- }
-}
+const TimingContext = React.createContext({
+ tasks: false,
+ timings: false,
+});
class ErrorBoundary extends React.Component<
{ children?: React.ReactNode },
@@ -141,8 +92,8 @@ class ClassWithMetrics extends React.Component<{
color = getRandomColor();
componentId = String.fromCharCode(i++);
- log(message: string) {
- measureTiming(
+ boundLog(message: string) {
+ log(
`%cComponent ${this.componentId}: ${message}`,
`color: ${this.color}`,
this.context
@@ -152,48 +103,48 @@ class ClassWithMetrics extends React.Component<{
constructor(props: { children?: React.ReactNode; dashed?: boolean }) {
super(props);
- this.log("constructor");
+ this.boundLog("constructor");
}
override componentWillMount() {
- this.log("componentWillMount");
+ this.boundLog("componentWillMount");
}
override componentWillReceiveProps() {
- this.log("componentWillReceiveProps");
+ this.boundLog("componentWillReceiveProps");
}
override componentWillUpdate() {
- this.log("componentWillUpdate");
+ this.boundLog("componentWillUpdate");
}
override componentDidMount() {
- this.log("componentDidMount");
+ this.boundLog("componentDidMount");
}
override componentDidUpdate() {
- this.log("componentDidUpdate");
+ this.boundLog("componentDidUpdate");
}
override shouldComponentUpdate() {
- this.log("shouldComponentUpdate");
+ this.boundLog("shouldComponentUpdate");
return true;
}
override getSnapshotBeforeUpdate() {
- this.log("getSnapshotBeforeUpdate");
+ this.boundLog("getSnapshotBeforeUpdate");
}
override componentWillUnmount() {
- this.log("componentWillUnmount");
+ this.boundLog("componentWillUnmount");
}
override render() {
- this.log("render");
+ this.boundLog("render");
return (
@@ -263,9 +214,9 @@ const useMetrics = () => {
const componentId = React.useMemo(() => String.fromCharCode(i++), []);
const withTiming = React.useContext(TimingContext);
- const log = React.useCallback(
+ const boundLog = React.useCallback(
(message: string) => {
- measureTiming(
+ log(
`%cComponent ${componentId}: ${message}`,
`color: ${color}`,
withTiming
@@ -274,18 +225,18 @@ const useMetrics = () => {
[withTiming]
);
- log("render");
+ boundLog("render");
const [s, forceUpdate] = React.useState({});
React.useMemo(function useMemo() {
- log("useMemo");
+ boundLog("useMemo");
}, []);
React.useInsertionEffect(
function useInsertionEffect() {
- log("useInsertionEffect");
+ boundLog("useInsertionEffect");
return function useInsertionEffect_cleanup() {
- log("useInsertionEffect cleanup");
+ boundLog("useInsertionEffect cleanup");
};
},
[s]
@@ -293,9 +244,9 @@ const useMetrics = () => {
React.useLayoutEffect(
function useLayoutEffect() {
- log("useLayoutEffect");
+ boundLog("useLayoutEffect");
return function useLayoutEffect_cleanup() {
- log("useLayoutEffect cleanup");
+ boundLog("useLayoutEffect cleanup");
};
},
[s]
@@ -303,15 +254,15 @@ const useMetrics = () => {
React.useEffect(
function useEffect() {
- log("useEffect");
+ boundLog("useEffect");
return function useEffect_cleanup() {
- log("useEffect cleanup");
+ boundLog("useEffect cleanup");
};
},
[s]
);
- return { log, color, componentId, forceUpdate };
+ return { log: boundLog, color, componentId, forceUpdate };
};
function FunctionWithMetrics({
@@ -403,21 +354,39 @@ export default function App() {
);
const Example: (() => JSX.Element) | undefined = examples[example!];
- const [withTiming, setTiming] = React.useState(false);
+ const [withTimings, setTiming] = React.useState(false);
+ const [withTasks, setTasks] = React.useState(false);
+ const contextValue = React.useMemo(
+ () => ({ timings: withTimings, tasks: withTasks }),
+ [withTimings, withTasks]
+ );
return (
- Timing {withTiming ? "enabled " : "disabled "}
+ Timing {withTimings ? "enabled " : "disabled "}
+
+
+
+ Tasks {withTasks ? "enabled " : "disabled "}
@@ -444,9 +413,11 @@ export default function App() {
))}
-
+
- {Example && }
+ {Example && (
+
+ )}
diff --git a/src/components/page-react-timings/tasks.ts b/src/components/page-react-timings/tasks.ts
new file mode 100644
index 0000000..98a0e07
--- /dev/null
+++ b/src/components/page-react-timings/tasks.ts
@@ -0,0 +1,96 @@
+const div = document.createElement("div");
+document.body.appendChild(div);
+
+export function syncTask(cb: (type: string) => void) {
+ (function syncCallback() {
+ cb("sync");
+ })();
+}
+export function microTask(cb: (type: string) => void) {
+ queueMicrotask(function microTaskCallback() {
+ cb("micro task");
+ });
+}
+export function userBlockingTask(cb: (type: string) => void) {
+ scheduler.postTask(
+ function userBlockingTaskCallback() {
+ cb("task (user-blocking)");
+ },
+ { priority: "user-blocking" }
+ );
+}
+export function userVisibleTask(cb: (type: string) => void) {
+ scheduler.postTask(
+ function userVisibleTaskCallback() {
+ cb("task (user-visible)");
+ },
+ { priority: "user-visible" }
+ );
+}
+export function backgroundTask(cb: (type: string) => void) {
+ scheduler.postTask(
+ function backgroundTaskCallback() {
+ cb("task (background)");
+ },
+ { priority: "background" }
+ );
+}
+export function animationTask(cb: (type: string) => void) {
+ requestAnimationFrame(function animationTaskCallback() {
+ cb("animation frame");
+ });
+}
+
+export function startAllTasks(cb: (type: string) => void) {
+ syncTask(cb);
+ microTask(cb);
+ userBlockingTask(cb);
+ userVisibleTask(cb);
+ backgroundTask(cb);
+ animationTask(cb);
+}
+
+function getNow(timings: boolean) {
+ if (!timings) {
+ return "";
+ }
+
+ return (
+ "Now: " +
+ performance.now().toFixed(1) +
+ "ms | Timeline: " +
+ document.timeline.currentTime +
+ "ms | "
+ );
+}
+
+export function log(
+ label: string,
+ color: string,
+ {
+ tasks,
+ timings = false,
+ }: {
+ tasks?: boolean;
+ timings?: boolean;
+ } = {}
+) {
+ if (!tasks) {
+ console.log(getNow(timings) + label, color);
+ return;
+ }
+
+ const timingStyle = [
+ "font-style: italic; text-decoration-line: underline",
+ "",
+ ];
+
+ const cb = (type: string) =>
+ console.log(
+ getNow(timings) + "%c" + type + "%c " + label,
+ ...timingStyle,
+ color
+ );
+
+ startAllTasks(cb);
+}
--
2.51.2
From 63eb3d2adc52fd9889df09af45f06f3ae73842b7 Mon Sep 17 00:00:00 2001
From: Ayc0
Date: Tue, 21 May 2024 16:07:46 +0200
Subject: [PATCH 2/7] fix getSnapshotBeforeUpdate
---
src/components/page-react-timings/App.tsx | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/components/page-react-timings/App.tsx b/src/components/page-react-timings/App.tsx
index 42c1e8a..59add50 100644
--- a/src/components/page-react-timings/App.tsx
+++ b/src/components/page-react-timings/App.tsx
@@ -133,6 +133,7 @@ class ClassWithMetrics extends React.Component<{
override getSnapshotBeforeUpdate() {
this.boundLog("getSnapshotBeforeUpdate");
+ return "";
}
override componentWillUnmount() {
--
2.51.2
From ae02ffdffdba3616ce9bf6751b16a66f5f8affa0 Mon Sep 17 00:00:00 2001
From: Ayc0
Date: Tue, 21 May 2024 16:22:18 +0200
Subject: [PATCH 3/7] add re-renders
---
src/components/page-react-timings/App.tsx | 29 ++++++++++++++++-------
1 file changed, 21 insertions(+), 8 deletions(-)
diff --git a/src/components/page-react-timings/App.tsx b/src/components/page-react-timings/App.tsx
index 59add50..0b8a5b5 100644
--- a/src/components/page-react-timings/App.tsx
+++ b/src/components/page-react-timings/App.tsx
@@ -349,10 +349,16 @@ const examples = {
function: ExampleWithFunction,
};
+function resetConsole() {
+ console.clear();
+ i = 65;
+}
+
export default function App() {
const [example, setExample] = React.useState(
null
);
+ const [, forRerender] = React.useState({});
const Example: (() => JSX.Element) | undefined = examples[example!];
const [withTimings, setTiming] = React.useState(false);
@@ -369,8 +375,7 @@ export default function App() {
- }
- >
-
- {this.props.children}
-
-
- );
- }
-}
-
-function ErrorThrower() {
- const [hasError, setError] = React.useState(false);
- if (hasError) {
- throw new Error("oops");
- }
- return (
- setError(true)} title="throw error">
- 💥
-
- );
-}
-
-function Suspenser() {
- const [hasSuspense, setSuspense] = React.useState(false);
- if (hasSuspense) {
- throw new Promise((res) => {});
- }
- return (
- setSuspense(true)} title="trigger infinite suspense">
- 🚧
-
- );
-}
-
-class ClassWithMetrics extends React.Component<{
- children?: React.ReactNode;
- dashed?: boolean;
-}> {
- static override contextType = TimingContext;
- declare context: React.ContextType;
-
- color = getRandomColor();
- componentId = String.fromCharCode(i++);
-
- boundLog(message: string) {
- log(
- `%cComponent ${this.componentId}: ${message}`,
- `color: ${this.color}`,
- this.context
- );
- }
-
- constructor(props: { children?: React.ReactNode; dashed?: boolean }) {
- super(props);
-
- this.boundLog("constructor");
- }
-
- override componentWillMount() {
- this.boundLog("componentWillMount");
- }
-
- override componentWillReceiveProps() {
- this.boundLog("componentWillReceiveProps");
- }
-
- override componentWillUpdate() {
- this.boundLog("componentWillUpdate");
- }
-
- override componentDidMount() {
- this.boundLog("componentDidMount");
- }
-
- override componentDidUpdate() {
- this.boundLog("componentDidUpdate");
- }
-
- override shouldComponentUpdate() {
- this.boundLog("shouldComponentUpdate");
- return true;
- }
-
- override getSnapshotBeforeUpdate() {
- this.boundLog("getSnapshotBeforeUpdate");
- return "";
- }
-
- override componentWillUnmount() {
- this.boundLog("componentWillUnmount");
- }
-
- override render() {
- this.boundLog("render");
- return (
-
-
- {this.componentId}
- this.forceUpdate()} title="re-render">
- 🔄
-
-
-
-
-
- {this.props.children}
-
-
- );
- }
-}
-
-class ClassWithChildrenWithMetrics extends ClassWithMetrics {
- override render() {
- this.boundLog("render");
- return (
-
-
- {this.componentId}*
- this.forceUpdate()} title="re-render">
- 🔄
-
-
-
-
-
-
-
-
-
-
- );
- }
-}
-
-function ExampleWithClass() {
- return (
-
-
-
-
-
-
-
-
-
-
- );
-}
-
-const useMetrics = () => {
- const color = React.useMemo(() => getRandomColor(), []);
- const componentId = React.useMemo(() => String.fromCharCode(i++), []);
- const withTiming = React.useContext(TimingContext);
-
- const boundLog = React.useCallback(
- (message: string) => {
- log(
- `%cComponent ${componentId}: ${message}`,
- `color: ${color}`,
- withTiming
- );
- },
- [withTiming]
- );
-
- boundLog("render");
- const [s, forceUpdate] = React.useState({});
-
- React.useMemo(function useMemo() {
- boundLog("useMemo");
- }, []);
-
- React.useInsertionEffect(
- function useInsertionEffect() {
- boundLog("useInsertionEffect");
- return function useInsertionEffect_cleanup() {
- boundLog("useInsertionEffect cleanup");
- };
- },
- [s]
- );
-
- React.useLayoutEffect(
- function useLayoutEffect() {
- boundLog("useLayoutEffect");
- return function useLayoutEffect_cleanup() {
- boundLog("useLayoutEffect cleanup");
- };
- },
- [s]
- );
-
- React.useEffect(
- function useEffect() {
- boundLog("useEffect");
- return function useEffect_cleanup() {
- boundLog("useEffect cleanup");
- };
- },
- [s]
- );
-
- return { log: boundLog, color, componentId, forceUpdate };
-};
-
-function FunctionWithMetrics({
- children,
- dashed,
-}: {
- children?: React.ReactNode;
- dashed?: boolean;
-}) {
- const { log, color, componentId, forceUpdate } = useMetrics();
-
- return (
-
-
- {componentId}
- forceUpdate({})} title="re-render">
- 🔄
-
-
-
-
-
{children}
-
- );
-}
-
-function FunctionWithChildrenWithMetrics(
- this: unknown,
- {
- children,
- }: {
- children?: React.ReactNode;
- }
-) {
- const { log, color, componentId, forceUpdate } = useMetrics();
-
- return (
-
-
- {componentId}*
- forceUpdate({})} title="re-render">
- 🔄
-
-
-
-
-
-
-
-
-
-
- );
-}
-
-function ExampleWithFunction() {
- return (
-
-
-
-
-
-
-
-
-
-
- );
-}
-
-const examples = {
- class: ExampleWithClass,
- function: ExampleWithFunction,
-};
-
-function resetConsole() {
- console.clear();
- i = 65;
-}
-
-export default function App() {
- const [example, setExample] = React.useState(
- null
- );
- const [, forRerender] = React.useState({});
- const Example: (() => JSX.Element) | undefined = examples[example!];
-
- const [withTimings, setTiming] = React.useState(false);
- const [withTasks, setTasks] = React.useState(false);
- const contextValue = React.useMemo(
- () => ({ timings: withTimings, tasks: withTasks }),
- [withTimings, withTasks]
- );
+import { LifeCycleTimings } from "./LifeCycleTimings";
+export function App() {
return (
-
-
- Timing {withTimings ? "enabled " : "disabled "}
- {
- resetConsole();
- setTiming((t) => !t);
- }}
- >
- {withTimings ? "️⌛" : "⏳"}
-
-
-
- Tasks {withTasks ? "enabled " : "disabled "}
- {
- resetConsole();
- setTasks((t) => !t);
- }}
- >
- {withTasks ? "️🪫" : "🔋"}
-
-
-
- Pick example:
- {
- resetConsole();
- setExample(null);
- }}
- >
- Remove all
-
- {
- resetConsole();
- forRerender({});
- }}
- >
- Re-render
-
- {Object.keys(examples).map((example) => (
- {
- if (examples[example as keyof typeof examples] === Example) {
- return;
- }
- resetConsole();
- setExample(example as keyof typeof examples);
- }}
- >
- {example}
-
- ))}
-
-
-
- {Example && (
-
- )}
-
-
-
+ <>
+
+ >
);
}
diff --git a/src/components/page-react-timings/LifeCycleTimings.tsx b/src/components/page-react-timings/LifeCycleTimings.tsx
new file mode 100644
index 0000000..de4ed87
--- /dev/null
+++ b/src/components/page-react-timings/LifeCycleTimings.tsx
@@ -0,0 +1,487 @@
+import React from "react";
+import { log } from "./tasks";
+
+const getRandomColor = () => {
+ return `lch(${Math.floor(Math.random() * 20) + 50}% ${
+ Math.floor(Math.random() * 50) + 50
+ } ${Math.floor(Math.random() * 360)})`;
+};
+
+let i = 65;
+
+const TimingContext = React.createContext({
+ tasks: false,
+ timings: false,
+});
+
+class ErrorBoundary extends React.Component<
+ { children?: React.ReactNode },
+ { error: boolean }
+> {
+ override state = {
+ error: false,
+ };
+
+ static getDerivedStateFromError() {
+ return {
+ error: true,
+ };
+ }
+
+ override render() {
+ if (this.state.error) {
+ return Oops
;
+ }
+
+ return (
+ ⏸️
+ }
+ >
+
+ {this.props.children}
+
+
+ );
+ }
+}
+
+function ErrorThrower() {
+ const [hasError, setError] = React.useState(false);
+ if (hasError) {
+ throw new Error("oops");
+ }
+ return (
+ setError(true)} title="throw error">
+ 💥
+
+ );
+}
+
+function Suspenser() {
+ const [hasSuspense, setSuspense] = React.useState(false);
+ if (hasSuspense) {
+ throw new Promise((res) => {});
+ }
+ return (
+ setSuspense(true)} title="trigger infinite suspense">
+ 🚧
+
+ );
+}
+
+function Legend() {
+ const style = {
+ width: "2ch",
+ display: "inline-block",
+ height: "0.5ex",
+ };
+ return (
+
+
+ {" "}
+ Component
+
+
+ Error +
+ Suspense boundary
+
+
+ Error was
+ thrown & caught
+
+
+ Suspense in
+ progress
+
+
+ );
+}
+
+class ClassWithMetrics extends React.Component<{
+ children?: React.ReactNode;
+}> {
+ static override contextType = TimingContext;
+ declare context: React.ContextType;
+
+ color = getRandomColor();
+ componentId = String.fromCharCode(i++);
+
+ boundLog(message: string) {
+ log(
+ `%cComponent ${this.componentId}: ${message}`,
+ `color: ${this.color}`,
+ this.context
+ );
+ }
+
+ constructor(props: { children?: React.ReactNode }) {
+ super(props);
+
+ console.log(this.context);
+
+ this.boundLog("constructor");
+ }
+
+ override componentWillMount() {
+ this.boundLog("componentWillMount");
+ }
+
+ override componentWillReceiveProps() {
+ this.boundLog("componentWillReceiveProps");
+ }
+
+ override componentWillUpdate() {
+ this.boundLog("componentWillUpdate");
+ }
+
+ override componentDidMount() {
+ this.boundLog("componentDidMount");
+ }
+
+ override componentDidUpdate() {
+ this.boundLog("componentDidUpdate");
+ }
+
+ override shouldComponentUpdate() {
+ this.boundLog("shouldComponentUpdate");
+ return true;
+ }
+
+ override getSnapshotBeforeUpdate() {
+ this.boundLog("getSnapshotBeforeUpdate");
+ return "";
+ }
+
+ override componentWillUnmount() {
+ this.boundLog("componentWillUnmount");
+ }
+
+ override render() {
+ this.boundLog("render");
+ return (
+
+
+ {this.componentId}
+ {
+ resetConsole();
+ this.forceUpdate();
+ }}
+ title="re-render"
+ >
+ 🔄
+
+
+
+
+
+ {this.props.children}
+
+
+ );
+ }
+}
+
+class ClassWithChildrenWithMetrics extends ClassWithMetrics {
+ override render() {
+ this.boundLog("render");
+ return (
+
+
+ {this.componentId}*
+ {
+ resetConsole();
+ this.forceUpdate();
+ }}
+ title="re-render"
+ >
+ 🔄
+
+
+
+
+
+
+
+
+
+
+ );
+ }
+}
+
+function ExampleWithClass() {
+ return (
+ <>
+
+
+
+
+
+
+
+
+
+
+
+ >
+ );
+}
+
+const useMetrics = () => {
+ const color = React.useMemo(() => getRandomColor(), []);
+ const componentId = React.useMemo(() => String.fromCharCode(i++), []);
+ const withTiming = React.useContext(TimingContext);
+ const elementRef = React.useRef(null);
+
+ const boundLog = React.useCallback(
+ (message: string) => {
+ log(
+ `%cComponent ${componentId}: ${message}`,
+ `color: ${color}`,
+ withTiming
+ );
+ },
+ [withTiming]
+ );
+
+ boundLog("render");
+ const [s, forceUpdate] = React.useState({});
+
+ React.useMemo(function useMemo() {
+ boundLog("useMemo");
+ }, []);
+
+ React.useInsertionEffect(
+ function useInsertionEffect() {
+ boundLog("useInsertionEffect " + (elementRef.current ? "node" : "null"));
+ return function useInsertionEffect_cleanup() {
+ boundLog(
+ "useInsertionEffect cleanup " + (elementRef.current ? "node" : "null")
+ );
+ };
+ },
+ [s]
+ );
+
+ React.useLayoutEffect(
+ function useLayoutEffect() {
+ boundLog("useLayoutEffect " + (elementRef.current ? "node" : "null"));
+ return function useLayoutEffect_cleanup() {
+ boundLog(
+ "useLayoutEffect cleanup " + (elementRef.current ? "node" : "null")
+ );
+ };
+ },
+ [s]
+ );
+
+ React.useEffect(
+ function useEffect() {
+ boundLog("useEffect " + (elementRef.current ? "node" : "null"));
+ return function useEffect_cleanup() {
+ boundLog("useEffect cleanup " + (elementRef.current ? "node" : "null"));
+ };
+ },
+ [s]
+ );
+
+ return {
+ log: boundLog,
+ color,
+ componentId,
+ forceUpdate,
+ elementRef: elementRef,
+ };
+};
+
+function FunctionWithMetrics({ children }: { children?: React.ReactNode }) {
+ const { log, color, componentId, forceUpdate, elementRef } = useMetrics();
+
+ return (
+
+
+ {componentId}
+ {
+ resetConsole();
+ forceUpdate({});
+ }}
+ title="re-render"
+ >
+ 🔄
+
+
+
+
+
{children}
+
+ );
+}
+
+function FunctionWithChildrenWithMetrics(this: unknown) {
+ const { log, color, componentId, forceUpdate, elementRef } = useMetrics();
+
+ return (
+
+
+ {componentId}*
+ {
+ resetConsole();
+ forceUpdate({});
+ }}
+ title="re-render"
+ >
+ 🔄
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+function ExampleWithFunction() {
+ return (
+ <>
+
+
+
+
+
+
+
+
+
+
+
+ >
+ );
+}
+
+const examples = {
+ class: ExampleWithClass,
+ function: ExampleWithFunction,
+};
+
+function resetConsole() {
+ console.clear();
+ i = 65;
+}
+
+export function LifeCycleTimings() {
+ const [example, setExample] = React.useState(
+ null
+ );
+ const [, forceUpdate] = React.useState({});
+ const Example: (() => JSX.Element) | undefined = examples[example!];
+
+ const [withTimings, setTiming] = React.useState(false);
+ const [withTasks, setTasks] = React.useState(false);
+ const contextValue = React.useMemo(
+ () => ({ timings: withTimings, tasks: withTasks }),
+ [withTimings, withTasks]
+ );
+
+ return (
+
+
+ Timing {withTimings ? "enabled " : "disabled "}
+ {
+ resetConsole();
+ setTiming((t) => !t);
+ }}
+ >
+ {withTimings ? "️⌛" : "⏳"}
+
+
+
+ Tasks {withTasks ? "enabled " : "disabled "}
+ {
+ resetConsole();
+ setTasks((t) => !t);
+ }}
+ >
+ {withTasks ? "️🪫" : "🔋"}
+
+
+
+ Pick example:
+ {
+ resetConsole();
+ setExample(null);
+ }}
+ >
+ Remove all
+
+ {
+ resetConsole();
+ forceUpdate({});
+ }}
+ >
+ Re-render
+
+ {Object.keys(examples).map((example) => (
+ {
+ if (examples[example as keyof typeof examples] === Example) {
+ return;
+ }
+ resetConsole();
+ setExample(example as keyof typeof examples);
+ }}
+ >
+ {example}
+
+ ))}
+
+
+
+ {Example && (
+
+ )}
+
+
+
+ );
+}
diff --git a/src/components/page-react-timings/index.tsx b/src/components/page-react-timings/index.tsx
index f69004e..1b7f77d 100644
--- a/src/components/page-react-timings/index.tsx
+++ b/src/components/page-react-timings/index.tsx
@@ -3,8 +3,8 @@ import React from "react";
import { render } from "react-dom";
import { createRoot } from "react-dom/client";
-import App from "./App.tsx";
-import Switcher, { isLegacyRoot } from "./Switcher.tsx";
+import { App } from "./App";
+import Switcher, { isLegacyRoot } from "./Switcher";
const rootElement = document.getElementById("root")!;
diff --git a/src/components/page-react-timings/tasks.ts b/src/components/page-react-timings/tasks.ts
index 98a0e07..786a8ec 100644
--- a/src/components/page-react-timings/tasks.ts
+++ b/src/components/page-react-timings/tasks.ts
@@ -1,3 +1,14 @@
+declare global {
+ const scheduler: {
+ postTask: (
+ task: Function,
+ opts: {
+ priority: "user-blocking" | "user-visible" | "background";
+ }
+ ) => void;
+ };
+}
+
const div = document.createElement("div");
document.body.appendChild(div);
--
2.51.2
From f6f6552080e237119873466630f1d22226f04552 Mon Sep 17 00:00:00 2001
From: Ayc0
Date: Tue, 21 May 2024 18:37:44 +0200
Subject: [PATCH 6/7] layout
---
.../page-react-timings/LifeCycleTimings.tsx | 170 ++++++++++--------
src/pages/react-timings.astro | 16 +-
2 files changed, 105 insertions(+), 81 deletions(-)
diff --git a/src/components/page-react-timings/LifeCycleTimings.tsx b/src/components/page-react-timings/LifeCycleTimings.tsx
index de4ed87..aaa4acb 100644
--- a/src/components/page-react-timings/LifeCycleTimings.tsx
+++ b/src/components/page-react-timings/LifeCycleTimings.tsx
@@ -78,9 +78,11 @@ function Legend() {
height: "0.5ex",
};
return (
-
+ <>
- {" "}
+ {" "}
Component
@@ -95,7 +97,7 @@ function Legend() {
Suspense in
progress
-
+ >
);
}
@@ -227,19 +229,16 @@ class ClassWithChildrenWithMetrics extends ClassWithMetrics {
function ExampleWithClass() {
return (
- <>
-
-
-
-
-
-
-
-
-
-
-
- >
+
+
+
+
+
+
+
+
+
+
);
}
@@ -376,19 +375,16 @@ function FunctionWithChildrenWithMetrics(this: unknown) {
function ExampleWithFunction() {
return (
- <>
-
-
-
-
-
-
-
-
-
-
-
- >
+
+
+
+
+
+
+
+
+
+
);
}
@@ -417,49 +413,9 @@ export function LifeCycleTimings() {
);
return (
-
-
- Timing {withTimings ? "enabled " : "disabled "}
- {
- resetConsole();
- setTiming((t) => !t);
- }}
- >
- {withTimings ? "️⌛" : "⏳"}
-
-
-
- Tasks {withTasks ? "enabled " : "disabled "}
- {
- resetConsole();
- setTasks((t) => !t);
- }}
- >
- {withTasks ? "️🪫" : "🔋"}
-
-
-
+ <>
+
Pick example:
- {
- resetConsole();
- setExample(null);
- }}
- >
- Remove all
-
- {
- resetConsole();
- forceUpdate({});
- }}
- >
- Re-render
-
{Object.keys(examples).map((example) => (
))}
-
-
- {Example && (
-
- )}
-
-
-
+
+ {Example && (
+ <>
+
+ {
+ resetConsole();
+ setExample(null);
+ }}
+ >
+ Remove all
+
+ {
+ resetConsole();
+ forceUpdate({});
+ }}
+ >
+ Re-render
+
+
+
+
+ Timing {withTimings ? "enabled " : "disabled "}
+ {
+ resetConsole();
+ setTiming((t) => !t);
+ }}
+ >
+ {withTimings ? "️⌛" : "⏳"}
+
+
+
+
+ Tasks {withTasks ? "enabled " : "disabled "}
+ {
+ resetConsole();
+ setTasks((t) => !t);
+ }}
+ >
+ {withTasks ? "️🪫" : "🔋"}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ >
+ )}
+ >
);
}
diff --git a/src/pages/react-timings.astro b/src/pages/react-timings.astro
index 7d4d181..1eff72e 100644
--- a/src/pages/react-timings.astro
+++ b/src/pages/react-timings.astro
@@ -13,14 +13,26 @@ import Page from '@layouts/Page.astro';