Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix inspect stack not returning all ancestors #693

Open
wants to merge 12 commits into
base: main
Choose a base branch
from

Conversation

km1chno
Copy link
Contributor

@km1chno km1chno commented Nov 4, 2024

Changes

Fixes #692

This PR is also necessary for #666

This PR aims to fix the issue with inspector stack that not all ancestors of inspected elements are discovered. It turns out that the hierarchy returned by getInspectorData() is already missing these ancestors, so we have to traverse the component tree ourselves.

The first node is the closestInstance in object returned by getInspectorDataViewAtPoint. To access parent node of a node, we look at node.return. This way we can simply traverse the whole path from first node up to the root. Along the way, we collect all necessary information and create a stack that is returned at the end. We use getInspectorDataForInstance(node) renderer function to obtain inspector data for given fiber node.

This version is a lot more accurate, from my testing it returns all the most used visible components (like <View>, <Text>, <Button>), which is already an improvement compared to the current solution.

Demos

The following are demos how the inspect stack looks like before and after changes from this PR. The component hierarchy of the app consists of several nested components, which have border for visualization.

Before

better_stack_demo_before.mov

After

better_stack_demo_after.mov

How Has This Been Tested:

Open test app, use inspector tool, use right click to show inspector stack.

Tested on Android:

  • expo-router
  • react-native-74
  • react-native-75
  • react-native-76

Test on iOS:

  • expo-router
  • react-native-75
  • react-native-76

@km1chno km1chno requested a review from kmagiera November 4, 2024 17:46
@km1chno km1chno self-assigned this Nov 4, 2024
Copy link

vercel bot commented Nov 4, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
radon-ide ✅ Ready (Inspect) Visit Preview 💬 Add feedback Nov 13, 2024 3:11pm

Copy link
Member

@kmagiera kmagiera left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please see my inline comments. I think it'd be good to test this on RN76 on both Android and iOS, as this is the only project that we have that's currently setup with the new architecture where some of the internals that you're accessing here may work differently.

packages/vscode-extension/lib/wrapper.js Outdated Show resolved Hide resolved
packages/vscode-extension/lib/wrapper.js Outdated Show resolved Hide resolved
packages/vscode-extension/lib/wrapper.js Outdated Show resolved Hide resolved
packages/vscode-extension/lib/wrapper.js Outdated Show resolved Hide resolved
packages/vscode-extension/lib/wrapper.js Outdated Show resolved Hide resolved
@km1chno
Copy link
Contributor Author

km1chno commented Nov 6, 2024

I tested this on rn76 (both Android and iOS), it looks like it's working 😄

Copy link
Member

@kmagiera kmagiera left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not a fan of using arrow function when without a specific reason. Specifically when defining top level methods.

packages/vscode-extension/lib/inspector.js Outdated Show resolved Hide resolved
packages/vscode-extension/lib/inspector.js Outdated Show resolved Hide resolved
packages/vscode-extension/lib/inspector.js Outdated Show resolved Hide resolved
packages/vscode-extension/lib/inspector.js Outdated Show resolved Hide resolved
Copy link
Member

@kmagiera kmagiera left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR seems to refactor some bits of the old codebase w/o qestioning why they've been implemented in the certain way. Specifically:

  1. inline requies
  2. try catch around measure
  3. Promise.all approach

The use of promises here doesn't seem to make a lot of sense. Before the role of promises was such that we can call async measure in parallel. This PR changes it and makes all measure calls sequential and thus potentially slower.

packages/vscode-extension/lib/inspector.js Outdated Show resolved Hide resolved
@km1chno
Copy link
Contributor Author

km1chno commented Nov 6, 2024

@kmagiera As for the Promise.all - I missed the fact that it makes the promise resolution parallel. I put it back because why not, it could be potentially faster this way in some scenarios, as you said.

I also changed the recursive procedure of traversing the tree into an iterative one, also could be a bit faster

Copy link
Member

@kmagiera kmagiera left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for addressing all the comments. This looks good now

Copy link
Member

@kmagiera kmagiera left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Appears like there are some issues with this change on React Native 76. Marking this as 'request changes" to avoid it being accidentally merged.

Copy link
Member

@kmagiera kmagiera left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some more inline comments in the code.

In general what worries me is that I don't understand what this PR is actually fixing. It links to an empty issue but there are no reproducable steps that would allow us to test before/after this change and see if it fixes anything. This is important as in the future, if someone wants to change something in this code, they may want to test again the scenario that this PR claims to fix.

packages/vscode-extension/lib/wrapper.js Show resolved Hide resolved
packages/vscode-extension/lib/wrapper.js Outdated Show resolved Hide resolved
packages/vscode-extension/lib/wrapper.js Outdated Show resolved Hide resolved
@km1chno
Copy link
Contributor Author

km1chno commented Nov 13, 2024

@kmagiera I updated #692 with proper bug report and steps to reproduce

Copy link
Member

@kmagiera kmagiera left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good now

height: viewHeight
};

stackElement = (inspectorData.source) ?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
stackElement = (inspectorData.source) ?
const stackElement = (inspectorData.source) ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, it appears like we can tell whether source is set before we call measure, so maybe we can skip calling measure altogether in such a case?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added an if statement before measure to check if source is absent and resolve the promise early in such case

@kmagiera
Copy link
Member

Will re-test again after changes and try to land this

@km1chno km1chno removed their assignment Nov 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Inspector stack is not returning all ancestors
3 participants