Analysis based react devtools backend #6188
Replies: 3 comments 2 replies
-
I wrote a related issue on the React side about DevTools protocol versions. Seems relevant so I'll link it here:
This sounds promising, although I don't have a very thorough understanding of how the backend stuff works at the moment. |
Beta Was this translation helpful? Give feedback.
-
Hmm, to be a little more concrete (and improve my understanding) I went through how things currently work and how they should be able to work with the react devtools backend living in the client. From what I can tell this should be able to work, but we definitely need support for persistent object IDs (https://github.com/RecordReplay/backend/issues/5144) first. Currently in every recording process we load a modified version of a specific version of the react devtools installHook function, and a modified version of the react devtools backend into the main window [1]: Any react on the page will detect the The backend does its usual thing, but instead of posting a "react-devtools-bridge" message to the frontend it has been modified from the stock backend to call a The devtools frontend read these annotations from the recording and feed them to the react devtools frontend, as if they had been received as messages from the backend. (Incidentally this doesn't check for the "react-devtools-bridge" kind, which looks like a bug, filed https://github.com/RecordReplay/devtools/issues/6132). [4] What would be good to do instead is to avoid loading the react devtools backend into the recording process, and change the methods in the devtools global hook so that they add annotations to the recording instead of trying to call into the backend. For example, in [2] the hook's onCommitFiberRoot wouldn't call handleCommitFiberRoot, but would add a "react-devtools-onCommitFiberRoot" annotation or something to the recording. The devtools frontend can read these annotations as in [4] and get any information it wants about the current state of the program when that annotation was added. Each annotation includes an The limitation we'll run into here though is that currently ValueFronts from different pauses are not comparable. So if onCommitFiberRoot is called repeatedly with the same root, by inspecting the annotations we can see all those calls but we can't tell whether the call is being made with the same root multiple times or different roots every time. It looks like this will break the backend pretty quickly. handleCommitFiberRoot (and many other places in the backend) call getOrGenerateFiberID, which maintains a We need persistent object IDs (https://github.com/RecordReplay/backend/issues/5144) in order to support functionality like At that point one potential remaining stumbling block would be if the react devtools backend methods like handleCommitFiberRoot mutate any state in the page or the page's objects which could affect the page's behavior or the behavior of later backend methods --- changes made to the page state at one pause will not be reflected in pauses at later points in the recording. I don't think this would be the case, e.g. the backend is using |
Beta Was this translation helpful? Give feedback.
-
Moving this to a discussion so we can continue discussing this approach. When we're ready to pick it up we can either move it back to an issue or make a new more actionable issue. |
Beta Was this translation helpful? Give feedback.
-
Currently we have a version of the react devtools backend which we load into every recording made using the replay browser. Any react on the page will detect this backend and call into it, and it will add annotations to the recording which clients inspecting the recording can read and use to reconstruct the react state at any point in the recording.
This approach works but it doesn't scale well in a couple of ways:
It would be better if we didn't load a specific version of the backend into each recording. There is already an interface between the devtools backend and the react code running on the page which works across different versions of react. If the client loaded both the frontend and the backend for the react devtools (where the versions always match), and inspected the recording to find all the sites where react would have called into the backend, it should be able to extract the necessary information from those sites to populate its copy of the backend with the react state changes made throughout the recording.
We should be able to find the sites where react would have called into the backend by loading a shim version of the backend into each recording which is much smaller and just annotates the recording with all the calls that react is making.
The main unknowns for me is understanding what information the backend needs from these sites in order to work, and how difficult it would be to get this information from the recording instead of values that are being passed in. I suspect the protocol is not expressive enough yet to deal with this use case. Mainly, each site will be a different pause point, and we don't have a way to compare objects between different pauses. So if the backend keeps track of metadata for a react object at one site, it won't be able to determine that object's metadata when it is accessed at a different site. We've wanted to address this limitation for a while though, and being able to improve the architecture of our react devtools support and address the above difficulties would be a good impetus for this.
Beta Was this translation helpful? Give feedback.
All reactions