@samitouri / QOS-React-2 / commits / f580d0ece7

Don't (re)serialize inspected elements either unless they have re-rendered since last inspected.

Brian Vaughn committed May 24, 2019 at 09:07 UTC f580d0ece7a973fccd67483f94df917156229c5c
4 files changed +28 -41
src/__tests__/__snapshots__/inspectedElementContext-test.js.snap
-23
@@ -28,29 +28,6 @@ exports[`InspectedElementContext should inspect the currently selected element:
28 }
29 `;
30
31 -exports[`InspectedElementContext should inspect the currently selected element: 2: Inspected element 2 2`] = `
32 -{
33 - "id": 2,
34 - "owners": null,
35 - "context": null,
36 - "events": null,
37 - "hooks": [
38 - {
39 - "id": 0,
40 - "isStateEditable": true,
41 - "name": "State",
42 - "value": 1,
43 - "subHooks": []
44 - }
45 - ],
46 - "props": {
47 - "foo": 1,
48 - "bar": "abc"
49 - },
50 - "state": null
51 -}
52 -`;
53 -
31 exports[`InspectedElementContext should not re-render a function with hooks if it did not update since it was last inspected: 1: mount 1`] = `
32 [root]
33 ▾ <Wrapper>
src/backend/renderer.js
+5 -9
@@ -1906,15 +1906,11 @@ export function attach(
1906 let mostRecentlyInspectedElementID: number | null = null;
1907 let mostRecentlyInspectedElement: InspectedElement | null = null;
1908
1909 - function inspectElement(id: number): InspectedElement | null {
1910 - // If this element has not been updated since it was last inspected, reuse the last value.
1911 - // This avoids re-invoking a function component with hooks.
1912 - // TODO We could send a special signal (e.g. true) to avoid serialization too.
1913 - if (
1914 - mostRecentlyInspectedElement !== null &&
1915 - mostRecentlyInspectedElementID === id
1916 - ) {
1917 - return mostRecentlyInspectedElement;
1909 + function inspectElement(id: number): InspectedElement | number | null {
1910 + // If this element has not been updated since it was last inspected, we don't need to re-run it.
1911 + // Instead we can just return the ID to indicate that it has not changed.
1912 + if (mostRecentlyInspectedElementID === id) {
1913 + return id;
1914 }
1915
1916 mostRecentlyInspectedElementID = id;
src/backend/types.js
+1 -1
@@ -170,7 +170,7 @@ export type RendererInterface = {
170 getPathForElement: (id: number) => Array<PathFrame> | null,
171 handleCommitFiberRoot: (fiber: Object, commitPriority?: number) => void,
172 handleCommitFiberUnmount: (fiber: Object) => void,
173 - inspectElement: (id: number) => InspectedElement | null,
173 + inspectElement: (id: number) => InspectedElement | number | null,
174 logElementToConsole: (id: number) => void,
175 overrideSuspense: (id: number, forceFallback: boolean) => void,
176 prepareViewElementSource: (id: number) => void,
src/devtools/views/Components/InspectedElementContext.js
+22 -8
@@ -83,8 +83,16 @@ function InspectedElementContextController({ children }: Props) {
83
84 // This effect handler invalidates the suspense cache and schedules rendering updates with React.
85 useEffect(() => {
86 - const onInspectedElement = (inspectedElement: InspectedElement | null) => {
87 - if (inspectedElement !== null) {
86 + const onInspectedElement = (
87 + inspectedElement: InspectedElement | number | null
88 + ) => {
89 + // A null value means that the element no longer exists in the backend.
90 + // If it's the same element that's currently selected, that selection will be removed once the Store updates.
91 + // If it's not- then we can just ignore it anyway.
92 + // Either way there is nothing we need to do in this case.
93 + // A numeric value indicates that the element hasn't changed since we last requested its data,
94 + // in which case we don't need to invalidate the cache and re-render anything in the DevTools.
95 + if (inspectedElement !== null && typeof inspectedElement === 'object') {
96 const id = inspectedElement.id;
97
98 inspectedElement = (({
@@ -141,13 +149,19 @@ function InspectedElementContextController({ children }: Props) {
149 // Update the $r variable.
150 bridge.send('selectElement', { id: selectedElementID, rendererID });
151
144 - const onInspectedElement = (inspectedElement: InspectedElement | null) => {
145 - if (
146 - inspectedElement !== null &&
147 - inspectedElement.id === selectedElementID
148 - ) {
152 + const onInspectedElement = (
153 + inspectedElement: InspectedElement | number | null
154 + ) => {
155 + if (inspectedElement !== null) {
156 // If this is the element we requested, wait a little bit and then ask for an update.
150 - timeoutID = setTimeout(sendRequest, 1000);
157 + if (inspectedElement === selectedElementID) {
158 + timeoutID = setTimeout(sendRequest, 1000);
159 + } else if (
160 + typeof inspectedElement === 'object' &&
161 + inspectedElement.id === selectedElementID
162 + ) {
163 + timeoutID = setTimeout(sendRequest, 1000);
164 + }
165 }
166 };
167