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