gabrieltrompiz

gabrieltrompiz

Member Since 3 years ago

Austin, TX

Experience Points
14
follower
Lessons Completed
11
follow
Lessons Completed
33
stars
Best Reply Awards
12
repos

134 contributions in the last year

Pinned
⚡ Collaboration application with GitHub integrated using React and Electron
⚡ Electra back-end with GraphQL and Apollo Server in node.js
⚡ Personal portfolio
⚡ Social Network Project for Web Development II class
⚡ Raven App back-end with Node.js, Express.js and socket.io
⚡ A declarative, efficient, and flexible JavaScript library for building user interfaces.
Activity
Nov
24
6 days ago
Nov
11
2 weeks ago
Activity icon
issue

gabrieltrompiz issue comment facebook/react

gabrieltrompiz
gabrieltrompiz

DevTools: Standalone should support multiple connected clients

The standalone DevTools uses a WebSocket to communicate with the backend (which is embedded within an application like a React Native app or a webpage running in Safari). It was reported that currently only one application can connect to the standalone DevTools at a time, but this limitation is unnecessary. A Node Server server can accept connections from multiple clients, and the DevTools architecture (and "store") support multiple connected renderers as well (for the case of multiple React DOM apps running on a page). So the Standalone DevTools should also be able to support multiple connected apps.

gabrieltrompiz
gabrieltrompiz

Sorry that I haven't been able to give updates on this issue. I have been a little tight on time.

I was able to assign the connectionIDs to the Bridge instances inside the Store and attach/remove the listeners of each one of them on connect/disconnect, but still the changes to the Store are really extensive and would take some time to get it done.

I'll try to pick this up again when I get some free time, but anyone should feel free to take it.

Nov
6
3 weeks ago
Nov
4
3 weeks ago
Nov
1
4 weeks ago
Oct
27
1 month ago
Oct
26
1 month ago
Activity icon
issue

gabrieltrompiz issue comment facebook/react

gabrieltrompiz
gabrieltrompiz

DevTools: Standalone should support multiple connected clients

The standalone DevTools uses a WebSocket to communicate with the backend (which is embedded within an application like a React Native app or a webpage running in Safari). It was reported that currently only one application can connect to the standalone DevTools at a time, but this limitation is unnecessary. A Node Server server can accept connections from multiple clients, and the DevTools architecture (and "store") support multiple connected renderers as well (for the case of multiple React DOM apps running on a page). So the Standalone DevTools should also be able to support multiple connected apps.

gabrieltrompiz
gabrieltrompiz

I agree with you about it probably not being common for people to want to connect multiple React backends to the DevTools, in my case I've never had that need. And actually don't know if it's worth to do so many changes just to achieve that.

Either way, I gave it a good thought and, as I see it, the connection ID is only being used by the Store, the backend does nothing but send it back and forth. So, I think it might be better if the connection ID is generated in the Store and is assigned to each one of the Bridge instances, that way the Store can recognize by itself the connection ID by "seeing" which Bridge instance sent a message. That way the operations array would remain untouched and the changes probably wouldn't be so disruptive.

Let me know what you think and in any case I can start working on this throughout this weekend.

Oct
23
1 month ago
Activity icon
issue

gabrieltrompiz issue comment facebook/react

gabrieltrompiz
gabrieltrompiz

DevTools: Standalone should support multiple connected clients

The standalone DevTools uses a WebSocket to communicate with the backend (which is embedded within an application like a React Native app or a webpage running in Safari). It was reported that currently only one application can connect to the standalone DevTools at a time, but this limitation is unnecessary. A Node Server server can accept connections from multiple clients, and the DevTools architecture (and "store") support multiple connected renderers as well (for the case of multiple React DOM apps running on a page). So the Standalone DevTools should also be able to support multiple connected apps.

gabrieltrompiz
gabrieltrompiz

Hey @bvaughn, I'd be happy to take this issue.

I started trying to solve it today and was able to set a unique connection id to each one of the connections (only one for the moment) and it is being sent inside the operations array. It now goes something like:

[
  1, // connection ID
  1, // renderer ID
  1, // root ID
  // string table and operations
]

That connection ID is created when a client connects to the standalone and is passed down to the connectToDevTools backend method. Then it is passed to the hook and it is consumed by the attach method from the renderer when the operations array is being created. In the case of the non-standalone versions, the connectionID defaults to 1. Made some changes on the operations listeners and got that done and working fine.

The problem I have right now is: the Store is capable of managing multiple renderers, but is not capable of managing multiple connections, this is because of two reasons:

  1. Inside the Store there is, for example, a ID to Element map (Map<number, Element>), but since the elements IDs are not unique across connections, probably it will be needed to create a connectionID map with the ID to Element map (Map<number, Map<number, Element>>). And I think those are some really breaking changes, considering that the Store is shared across all the DevTools versions and some of the exposed methods of the store would now require the connectionID as a parameter (probably would just send 1 as connection ID in the non-standalone versions, maybe default it to 1 so the non-standalone versions are not changed?).
  2. We need to find a way to accept multiple connections. In my opinion there are 2 approaches to this: make the frontend bridge listen to multiple connections/sockets or make the Store have multiple bridges, one per connection (I think the latter might be easier to implement).

I think one road that could be taken to solve the point 1 would be to find a way to treat the new connections as other renderers, so they are considered like a renderer inside the Store and the changes wouldn't be so disruptive (actually I think the connection ID would not be necessary in the operations array, not quite sure yet). The goal here would be to ensure the renderer IDs are unique across different connections, might work. So, just wanted to know your thoughts on this issue since it hasn't been discussed in ~5 months.

Oct
22
1 month ago
push

gabrieltrompiz push gabrieltrompiz/react

gabrieltrompiz
gabrieltrompiz

Support disabling spurious act warnings with a global environment flag (#22561)

  • Extract act environment check into function

act checks the environment to determine whether to fire a warning. We're changing how this check works in React 18. As a first step, this refactors the logic into a single function. No behavior changes yet.

  • Use IS_REACT_ACT_ENVIRONMENT to disable warnings

If IS_REACT_ACT_ENVIRONMENT is set to false, we will suppress any act warnings. Otherwise, the behavior of act is the same as in React 17: if jest is defined, it warns.

In concurrent mode, the plan is to remove the jest check and only warn if IS_REACT_ACT_ENVIRONMENT is true. I have not implemented that part yet.

gabrieltrompiz
gabrieltrompiz

Replace global jest heuristic with IS_REACT_ACT_ENVIRONMENT (#22562)

  • Remove jest global check in concurrent roots

In concurrent mode, instead of checking jest, we check the new IS_REACT_ACT_ENVIRONMENT global. The default behavior is false.

Legacy mode behavior is unchanged.

React's own internal test suite use a custom version of act that works by mocking the Scheduler — rather than the "real" act used publicly. So we don't enable the flag in our repo.

  • Warn if act is called in wrong environment

Adds a warning if act is called but IS_REACT_ACT_ENVIRONMENT is not enabled. The goal is to prompt users to correctly configure their testing environment, so that if they forget to use act in a different test, we can detect and warn about.

It's expected that the environment flag will be configured by the testing framework. For example, a Jest plugin. We will link to the relevant documentation page, once it exists.

The warning only fires in concurrent mode. Legacy roots will keep the existing behavior.

gabrieltrompiz
gabrieltrompiz
gabrieltrompiz
gabrieltrompiz

Hydrate using SuspenseComponent as the parent (#22582)

  • Add a failing test for Suspense hydration

  • Include salazarm's changes to the test

  • The hydration parent of a suspense boundary should be the boundary itself

This eventually got set when we popped back out of its children but it doesn't start out that way.

This fixes it so that the boundary parent is always the suspense boundary.

  • We now need to log errors with a suspense boundary as a parent

For now, we just log this with commentNode.parentNode as the parent for purposes of the error message.

  • Make a special getFirstHydratableChildWithinSuspenseInstance

We currently call getNextHydratableSibling but conceptually it's the child of the boundary. It just happens to be that when we use comment nodes, we need to call nextSibling in the DOM.

This makes this separation a bit clearer.

  • Sync old fork

Co-authored-by: Dan Abramov [email protected]

gabrieltrompiz
gabrieltrompiz

DevTools: Include Edge in browser name detection (#22584)

gabrieltrompiz
gabrieltrompiz
gabrieltrompiz
gabrieltrompiz

Upgrade useInsertionEffect to stable (#22589)

@huozhi tried this out and says it's working as expected. I think we can go ahead and move this into the stable channel, so that it is available in the React 18 alpha releases.

gabrieltrompiz
gabrieltrompiz

DevTools: Fix passing extensionId in evaled postMessage calls (#22590)

gabrieltrompiz
gabrieltrompiz

Clear extra nodes if there's a hydration mismatch within a suspense boundary (#22592)

  • Clear extra nodes if there's a mismatch within a suspense boundary

This usually happens when we exit out a DOM node but a suspense boundary is a virtual DOM node and we didn't do it in that case because we took a short cut by calling resetHydrationState directly since we know we won't need to pop.

  • Tighten up the types of getFirstHydratableChild

We currently call getFirstHydratableChild to step into the children of a suspense boundary. This can be a text node or a suspense boundary which isn't compatible with getFirstHydratableChild, and we cheat the type.

This accidentally works because .firstChild always returns null on those nodes in the DOM.

This just makes that explicit.

gabrieltrompiz
gabrieltrompiz

Support nonce option to be passed to inline scripts (#22593)

gabrieltrompiz
gabrieltrompiz

[Fizz] Add option to inject bootstrapping script tags after the shell is injected (#22594)

  • Add option to inject bootstrap scripts

These are emitted right after the shell as flushed.

  • Update ssr fixtures to use bootstrapScripts instead of manual script tag

  • Add option to FB renderer too

gabrieltrompiz
gabrieltrompiz

Dev Tools: Relax constraint on passing extensionId for backend init (#22597)

gabrieltrompiz
gabrieltrompiz
gabrieltrompiz
gabrieltrompiz

Scheduling Profiler: De-emphasize React internal frames (#22588)

This commit adds code to all React bundles to explicitly register the beginning and ending of the module. This is done by creating Error objects (which capture the file name, line number, and column number) and passing them explicitly to a DevTools hook (when present).

Next, as the Scheduling Profiler logs metadata to the User Timing API, it prints these module ranges along with other metadata (like Lane values and profiler version number).

Lastly, the Scheduling Profiler UI compares stack frames to these ranges when drawing the flame graph and dims or de-emphasizes frames that fall within an internal module.

The net effect of this is that user code (and 3rd party code) stands out clearly in the flame graph while React internal modules are dimmed.

Internal module ranges are completely optional. Older profiling samples, or ones recorded without the React DevTools extension installed, will simply not dim the internal frames.

gabrieltrompiz
gabrieltrompiz

Scheduling Profiler: Add marks for component effects (mount and unmount) (#22578)

DevTools (and its profilers) should not require users to be familiar with React internals. Although the scheduling profiler includes a CPU sample flame graph, it's there for advanced use cases and shouldn't be required to identify common performance issues.

This PR proposes adding new marks around component effects. This will enable users to identify components with slow effect create/destroy functions without requiring them to dig through the call stack. (Once #22529 lands, these new marks will also include component stacks, making them more useful still.)

For example, here's a profile with a long-running effect. Without this change, it's not clear why the effects phase takes so long. After this change, it's more clear why that the phase is longer because of a specific component.

We may consider adding similar marks around render phase hooks like useState, useReducer, useMemo. I avoided doing that in this PR because it would be a pretty pervasive change to the ReactFiberHooks file.

Note that this change should have no effect on production bundles since everything is guarded behind a profiling feature flag.

Going to tag more people than I normally would for this pR, since it touches both reconciler and DevTools packages. Feel free to ignore though if you don't have strong feelings.

Note that although this PR adds new marks to the scheduling profiler, it's done in a way that's backwards compatible for older profiles.

gabrieltrompiz
gabrieltrompiz

Scheduling Profiler does not warn about long transitions (#22614)

gabrieltrompiz
gabrieltrompiz

Initial implementation of cache cleanup (#22510)

This is an initial, partial implementation of a cleanup mechanism for the experimental Cache API. The idea is that consumers of the Cache API can register to be informed when a given Cache instance is no longer needed so that they can perform associated cleanup tasks to free resources stored in the cache. A canonical example would be cancelling pending network requests.

An overview of the high-level changes:

  • Changes the Cache type from a Map of cache instances to be an object with the original Map of instances, a reference count (to count roughly "active references" to the cache instances - more below), and an AbortController.
  • Adds a new public API, unstable_getCacheSignal(): AbortSignal, which is callable during render. It returns an AbortSignal tied to the lifetime of the cache - developers can listen for the 'abort' event on the signal, which React now triggers when a given cache instance is no longer referenced.
    • Note that AbortSignal is a web standard that is supported by other platform APIs; for example a signal can be passed to fetch() to trigger cancellation of an HTTP request.
  • Implements the above - triggering the 'abort' event - by handling passive mount/unmount for HostRoot and CacheComponent fiber nodes.

Cases handled:

  • Aborted transitions: we clean up a new cache created for an aborted transition
  • Suspense: we retain a fresh cache instance until a suspended tree resolves

For follow-ups:

  • When a subsequent cache refresh is issued before a previous refresh completes, the refreshes are queued. Fresh cache instances for previous refreshes in the queue should be cleared, retaining only the most recent cache. I plan to address this in a follow-up PR.
  • If a refresh is cancelled, the fresh cache should be cleaned up.
gabrieltrompiz
gabrieltrompiz

Expand act warning to cover all APIs that might schedule React work (#22607)

  • Move isActEnvironment check to function that warns

I'm about to fork the behavior in legacy roots versus concurrent roots even further, so I'm lifting this up so I only have to fork once.

  • Lift mode check, too

Similar to previous commit. I only want to check this once. Not for performance reasons, but so the logic is easier to follow.

  • Expand act warning to include non-hook APIs

In a test environment, React warns if an update isn't wrapped with act — but only if the update originates from a hook API, like useState.

We did it this way for backwards compatibility with tests that were written before the act API was introduced. Those tests didn't require act, anyway, because in a legacy root, all tasks are synchronous except for useEffect.

However, in a concurrent root, nearly every task is asynchronous. Even tasks that are synchronous may spawn additional asynchronous work. So all updates need to be wrapped with act, regardless of whether they originate from a hook, a class, a root, or any other type of component.

This commit expands the act warning to include any API that triggers an update.

It does not currently account for renders that are caused by a Suspense promise resolving; those are modelled slightly differently from updates. I'll fix that in the next step.

I also removed the check for whether an update is batched. It shouldn't matter, because even a batched update can spawn asynchronous work, which needs to be flushed by act.

This change only affects concurrent roots. The behavior in legacy roots is the same.

  • Expand act warning to include Suspense resolutions

For the same reason we warn when an update is not wrapped with act, we should warn if a Suspense promise resolution is not wrapped with act. Both "pings" and "retries".

Legacy root behavior is unchanged.

gabrieltrompiz
gabrieltrompiz

Remove warning for dangling passive effects (#22609)

In legacy mode, a test can get into a situation where passive effects are "dangling" — an update finished, and scheduled some passive effects, but the effects don't flush.

This is why React warns if you don't wrap updates in act. The act API is responsible for flushing passive effects. But there are some cases where the act API (in legacy roots) intentionally doesn't warn, like updates that originate from roots and classes. It's possible those updates will render children that contain useEffect. Because of this, dangling effects are still possible, and React doesn't warn about it.

So we implemented a second act warning for dangling effects.

However, in concurrent roots, we now enforce that all APIs that schedule React work must be wrapped in act. There's no scenario where dangling passive effects can happen that doesn't already trigger the warning for updates. So the dangling effects warning is redundant.

The warning was never part of a public release. It was only enabled in concurrent roots.

So we can delete it.

commit sha: 3c4c1c4703e8f7362370c44a48ac9348229e3791

push time in 1 month ago
Oct
20
1 month ago
Oct
15
1 month ago
Activity icon
delete

gabrieltrompiz in gabrieltrompiz/react delete branch reattachment-splash-page-listeners

deleted time in 1 month ago
push

gabrieltrompiz push gabrieltrompiz/react

gabrieltrompiz
gabrieltrompiz

Prevent errors/crashing when multiple installs of DevTools are present (#22517)

Summary

This commit is a proposal for handling duplicate installation of DevTools, in particular scoped to duplicates such as a dev build or the internal versions of DevTools installed alongside the Chrome Web Store extension.

Specifically, this commit makes it so when another instance of the DevTools extension is installed alongside the extension installed from the Chrome Web Store, we don't produce a stream of errors or crash Chrome, which is what would usually happen in this case.

Detecting Duplicate Installations

  • First, we check what type of installation the extension is: from the Chrome Web Store, the internal build of the extension, or a local development build.
  • If the extension is from the Chrome Web Store:
    • During initialization, we first check if the internal or local builds of the extension have already been installed and are enabled. To do this, we send a cross-extension message to the internal and local builds of the extension using their extension IDs.
      • We can do this because the extension ID for the internal build (and for the Chrome Web Store) is a stable ID.
      • For the local build, at build time we hardcode a key in the manifest.json which allows us to have a stable ID even for local builds.
    • If we detect that the internal or local extensions are already installed, then we skip initializing the current extension altogether so as to not conflict with the other versions. This means we don't initialize the frontend or the backend at all.
  • If the extension is the Internal Build:
    • During initialization, we first check if the local builds of the extension has already been installed and is enabled. To do this, we send a cross-extension message to the local build of the extension using its extension ID.
      • We can do this for the local build because at build time we hardcode a key in the manifest.json which allows us to have a stable ID even for local builds.
    • If we detect that the local extension is already installed, then we skip initializing the current extension altogether so as to not conflict with the that version. This means we don't initialize the frontend or the backend at all.
  • If the extension is a Local Dev Build:
    • Since other extensions check for the existence of this extension and disable themselves if they detect it, we don't need any special handling during initialization and assume that there are no duplicate extensions. This means that we will generally prefer keeping this extension enabled.

This behavior means that the order of priority for keeping an extension enabled is the following:

  1. Local build
  2. Internal build
  3. Public build

Preventing duplicate backend initialization

Note that the backend is injected and initialized by the content script listening to a message posted to the inspected window (via postMessage). Since the content script will be injected twice, once each by each instance of the extension, even if we initialize the extension once, both content scripts would still receive the single message posted from the single frontend, and it would then still inject and initialize the backend twice.

In order to prevent this, we also add the extension ID to the message for injecting the backend. That way each content script can check if the message comes from its own extension, and if not it can ignore the message and avoid double injecting the backend.

Other approaches

  • I considered using the chrome.management API generally to detect other installations, but that requires adding additional permissions to our production extension, which didn't seem ideal.
  • I also considered a few options of writing a special flag to the inspected window and checking for it before initializing the extension. However, it's hard to avoid race conditions in that case, and it seemed more reliable to check specifically for the WebStore extension, which is realistically where we would encounter the overlap.

Rollout

  • This commit needs to be published and rolled out to the Chrome Web Store first.
  • After this commit is published to the Chrome Web Store, any duplicate instances of the extension that are built and installed after this commit will no longer conflict with the Chrome Web Store version.

Next Steps

  • In a subsequent PR, I will extend this code to show a warning when duplicate extensions have been detected.

Part of #22486

How did you test this change?

Basic Testing

  • yarn flow
  • yarn test
  • yarn test-build-devtools

Double installation testing

Testing double-installed extensions for this commit is tricky because we are relying on the extension ID of the internal and Chrome Web Store extensions, but we obviously can't actually test the Web Store version (since we can't modify the already published version).

In order to simulate duplicate extensions installed, I did the following process:

  • Built separate extensions where I hardcoded a constant for whether the extension is internal or public (e.g. EXTENSION_INSTALLATION_TYPE = 'internal'). Then I installed these built extensions corresponding to the "internal" and "Web Store" builds.
  • Build and run the regular development extension (with yarn build:chrome:dev && yarn test:chrome), using the extension IDs of the previously built extensions as the "internal" and "public" extension IDs.

With this set up in place, I tested the following on pages both with and without React:

  • When only the local extension enabled, DevTools works normally.
  • When only the "internal" extension enabled, DevTools works normally.
  • When only the "public" extension enabled, DevTools works normally.
  • When "internal" and "public" extensions are installed, "public" extension is disabled and "internal" extension works normally.
  • When the local extension runs alongside the other extensions, other extensions disable themselves and local build works normally.
  • When we can't recognize what type of build the extension corresponds to, we show an error.
  • When all 3 extensions are installed and enabled in all different combinations, DevTools no longer produces errors or crashes Chrome, and works normally.
gabrieltrompiz
gabrieltrompiz

Enable scheduling profiler for RN FB profiling builds (#22566)

gabrieltrompiz
gabrieltrompiz

Reattachment of the splash page event listeners (#22558) (#22560)

gabrieltrompiz
gabrieltrompiz

Show warning in UI when duplicate installations of DevTools extension are detected (#22563)

gabrieltrompiz
gabrieltrompiz

DevTools prepare release script resets patch version when bumping minor (#22568)

gabrieltrompiz
gabrieltrompiz
gabrieltrompiz
gabrieltrompiz

Only show DevTools warning about unrecognized build in Chrome (#22571)

commit sha: b72dc8e9300f5ae997f7f5cfcd79b604cca3df0c

push time in 1 month ago
Oct
14
1 month ago
push

gabrieltrompiz push gabrieltrompiz/react

gabrieltrompiz
gabrieltrompiz

Typo on typing of disconnection callback

commit sha: 08ba0d91bd4579ff61a40de484a5f2901a345187

push time in 1 month ago
push

gabrieltrompiz push gabrieltrompiz/react

gabrieltrompiz
gabrieltrompiz

Consistency in the naming of disconnection callback

commit sha: f05009aaeb10fb4bbb9fb98b266cdbf5c93567a4

push time in 1 month ago
open pull request

gabrieltrompiz wants to merge facebook/react

gabrieltrompiz
gabrieltrompiz

Reattachment of the splash page event listeners (#22558)

Summary

Prevents the splash page from becoming unresponsive after the disconnection of a client (issue #22558). A onDisconnect callback was added to the -core package and is used to re-attach the event listener to the HTML elements in the splash page.

How did you test this change?

Connected and disconnected multiple times a client to the standalone DevTools and the listeners are now attached and working. Was able to copy both script tags and go to the Profiler tab.

gabrieltrompiz
gabrieltrompiz

I had to move these query selectors inside the method because they kept referencing the past elements before the disconnection and didn't show the "Copied to clipboard" message.

pull request

gabrieltrompiz merge to facebook/react

gabrieltrompiz
gabrieltrompiz

Reattachment of the splash page event listeners (#22558)

Summary

Prevents the splash page from becoming unresponsive after the disconnection of a client (issue #22558). A onDisconnect callback was added to the -core package and is used to re-attach the event listener to the HTML elements in the splash page.

How did you test this change?

Connected and disconnected multiple times a client to the standalone DevTools and the listeners are now attached and working. Was able to copy both script tags and go to the Profiler tab.

pull request

gabrieltrompiz pull request facebook/react

gabrieltrompiz
gabrieltrompiz

Reattachment of the splash page event listeners (#22558)

Summary

Prevents the splash page from becoming unresponsive after the disconnection of a client (issue #22558). A onDisconnect callback was added to the -core package and is used to re-attach the event listener to the HTML elements in the splash page.

How did you test this change?

Connected and disconnected multiple times a client to the standalone DevTools and the listeners are now attached and working. Was able to copy both script tags and go to the Profiler tab.

Activity icon
created branch

gabrieltrompiz in gabrieltrompiz/react create branch reattachment-splash-page-listeners

createdAt 1 month ago
Activity icon
fork

gabrieltrompiz forked facebook/react

⚡ A declarative, efficient, and flexible JavaScript library for building user interfaces.
gabrieltrompiz MIT License Updated
fork time in 1 month ago
Activity icon
issue

gabrieltrompiz issue comment facebook/react

gabrieltrompiz
gabrieltrompiz

Standalone Devtools splash page unresponsive after client disconnects

Website or app

Any client that connects to the standalone DevTools

Repro steps

While using the standalone DevTools app:

  1. Connect a client to the DevTools
  2. Disconnect that client and you should be redirected to the introduction page

The event listeners are not re-attached to the splash page elements after the client disconnects. The <script> tags that can be copied on click and the "Profiler tab" link stop working.

How often does this bug happen?

Every time

DevTools package (automated)

No response

DevTools version (automated)

No response

Error message (automated)

No response

Error call stack (automated)

No response

Error component stack (automated)

No response

GitHub query string (automated)

No response

gabrieltrompiz
gabrieltrompiz
Activity icon
issue

gabrieltrompiz issue comment facebook/react

gabrieltrompiz
gabrieltrompiz

Standalone Devtools splash page unresponsive after client disconnects

Website or app

Any client that connects to the standalone DevTools

Repro steps

While using the standalone DevTools app:

  1. Connect a client to the DevTools
  2. Disconnect that client and you should be redirected to the introduction page

The event listeners are not re-attached to the splash page elements after the client disconnect. The <script> tags that can be copied on click and the "Profile tab" link stop working.

How often does this bug happen?

Every time

DevTools package (automated)

No response

DevTools version (automated)

No response

Error message (automated)

No response

Error call stack (automated)

No response

Error component stack (automated)

No response

GitHub query string (automated)

No response

gabrieltrompiz
gabrieltrompiz

I was thinking about two ways to fix this issue: set a MutationObserver to re-attach the listeners when the contents of the root node are changed, or add a onShutdown callback to the DevToolsUI in the core of the standalone version and re-attach the listeners on that callback.

Activity icon
delete

gabrieltrompiz in gabrieltrompiz/react delete branch profiler-no-connected-clients

deleted time in 1 month ago
Oct
13
1 month ago
Activity icon
issue

gabrieltrompiz issue comment facebook/react

gabrieltrompiz
gabrieltrompiz

Allow to use the Profiler when no client is connected in standalone DevTools

Summary

Allows the Profiler tab to be used without the need of having a connected client in the DevTools standalone version (issue: #22127). The option to open the Profiler was added to the introduction/greeting page and redirects the user to the DevTools component. The impact in the DevTools component is minimum since no changes were made directly to it, only the react-devtools-core and the splash page were modified. As I mentioned in the issue discussion, a fake Bridge and Store were created in order to render the DevTools, there might exist a better workaround and should be reviewed. Also, the idea was to open the Profiler tab by default, but there are two props that can affect that behaviour: overrideTab (which prevents the tab from being changed because it is constantly overridden) and defaultTab (which sets the initial value for the LocalStorage entry that contains the tab that is open, but if a value is already stored in the LocalStorage, it is returned and the defaultValue is not used). It means that to change that behaviour it would be necessary to add an extra prop to the DevTools component and change the way the opened tab is selected at first.

How did you test this change?

It was tested by building and running the DevTools with the changes made. The instruction splash page would look like this: Screen Shot 2021-10-13 at 12 49 27 PM After pressing the "Profiler tab" link, it redirects the user to the DevTools: Screen Shot 2021-10-13 at 12 50 58 PM If a user loads a saved profile, the profiler can be used as usual: Screen Shot 2021-10-13 at 12 51 40 PM And when a connection is established with a client it updates and show the component tree and allows the profiler to record activity: Screen Shot 2021-10-13 at 2 05 24 PM

gabrieltrompiz
gabrieltrompiz

Oops, it seems the pipeline failed while installing a cached Yarn package. That's odd. Should I rerun it?

Activity icon
issue

gabrieltrompiz issue comment facebook/react

gabrieltrompiz
gabrieltrompiz

Allow to use the Profiler when no client is connected in standalone DevTools

Summary

Allows the Profiler tab to be used without the need of having a connected client in the DevTools standalone version (issue: #22127). The option to open the Profiler was added to the introduction/greeting page and redirects the user to the DevTools component. The impact in the DevTools component is minimum since no changes were made directly to it, only the react-devtools-core and the splash page were modified. As I mentioned in the issue discussion, a fake Bridge and Store were created in order to render the DevTools, there might exist a better workaround and should be reviewed. Also, the idea was to open the Profiler tab by default, but there are two props that can affect that behaviour: overrideTab (which prevents the tab from being changed because it is constantly overridden) and defaultTab (which sets the initial value for the LocalStorage entry that contains the tab that is open, but if a value is already stored in the LocalStorage, it is returned and the defaultValue is not used). It means that to change that behaviour it would be necessary to add an extra prop to the DevTools component and change the way the opened tab is selected at first.

How did you test this change?

It was tested by building and running the DevTools with the changes made. The instruction splash page would look like this: Screen Shot 2021-10-13 at 12 49 27 PM After pressing the "Profiler tab" link, it redirects the user to the DevTools: Screen Shot 2021-10-13 at 12 50 58 PM If a user loads a saved profile, the profiler can be used as usual: Screen Shot 2021-10-13 at 12 51 40 PM And when a connection is established with a client it updates and show the component tree and allows the profiler to record activity: Screen Shot 2021-10-13 at 2 05 24 PM

gabrieltrompiz
gabrieltrompiz

There we go. I think we're good now.

Thanks for the help and for your time!

push

gabrieltrompiz push gabrieltrompiz/react

gabrieltrompiz
gabrieltrompiz

Modified the default tab key when opening DevTools in "Profiler" mode

commit sha: cd728ea082f33abde09ec891ce7cded6be3b778f

push time in 1 month ago
Previous