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

Remove Calls to User Timing API #18417

Merged
merged 1 commit into from Mar 30, 2020
Merged

Remove Calls to User Timing API #18417

merged 1 commit into from Mar 30, 2020

Conversation

gaearon
Copy link
Collaborator

@gaearon gaearon commented Mar 28, 2020

This removes calls to the User Timing API in development.

There are several reasons why we want to do this.

  • Inaccurate timings. When we originally added it, we didn't have any profiling tools with React-specific knowledge. So we used what we could. Unfortunately, User Timings API was originally designed for cases like "loading page", and not for marking thousands of components. So it adds a lot of overhead. We've seen cases in hot paths where the User Timing API calls themselves account for over 30% of the rendering time. This means the measurements are skewed and often misleading. And since you can only get them in DEV mode, they're even worse. To solve this, we introduced React Profiler and special profiling buidls that give you much more accurate timings over a year ago, and we recommend using it.

  • Insufficient programmatic API. While User Timings API offers a way to observe measures, this API isn't well-suited for React's use cases either. Both in the open source community and internally at Facebook we've seen very complicated code attempting to parse data out of the performance markers. These approaches are fragile because they have to parse metadata out of strings. As an alternative, we added the <React.Profiler> component to gather measurements programmatically.

  • Bugs and maintenance burden. Supporting this has created a significant maintenance burden. The way the User Timing API is designed doesn't match how React works so we have to jump through a lot of hoops to play nice with it. Our support for it is pretty buggy and those bugs are very hard to fix. This is impeding refactors that would let us improve React's memory usage and make it faster, for example. Now that we have better alternatives, the cost of this is prohibitive compared to the value it provides.

Isn't This a Breaking Change?

This is not a breaking change because this utility has always been DEV-only. It is not enabled even in the Profiling builds. We reserve the right to change DEV-only behavior between versions. In this case, making this change would likely make React faster in development at the cost of some annoyance (learning to use a different and more accurate tool). There are clearly downsides, like losing the ability to see different markers side by side. Maybe we can solve them in the longer term, as described in next section.

Can We Add Them Back?

I think we could, eventually. The last version of the standard addressed some of the pain points, including the ability to attach metadata and (seemingly) the ability to specify custom timestamps. That might allow us to remove a lot of implementation complexity. However, we would still need to rip out this implementation since the new one would be significantly different. Additionally, we still wouldn't feel comfortable adding this back until we're sure that the performance penalties in major browsers have been addressed. For example, in the past we've seen these bugs unsolved for years.

Blockers

We have some blockers at FB where we rely on these in production as an experiment. That was a bad idea. See D20720369 and D20720332 for possible paths forward. We'll need to resolve that before merging.

@facebook-github-bot facebook-github-bot added CLA Signed React Core Team Opened by a member of the React Core Team labels Mar 28, 2020
@codesandbox-ci
Copy link

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit bf41bd2:

Sandbox Source
festive-feistel-swcy9 Configuration

@sizebot
Copy link

sizebot commented Mar 28, 2020

Details of bundled changes.

Comparing: 5bd1bc2...bf41bd2

react-native-renderer

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
ReactNativeRenderer-dev.js -2.2% -2.2% 649.65 KB 635.19 KB 140.37 KB 137.34 KB RN_OSS_DEV
ReactFabric-dev.js -2.3% -2.2% 631.51 KB 617.05 KB 135.96 KB 132.94 KB RN_OSS_DEV
ReactFabric-prod.js 0.0% 0.0% 258.68 KB 258.68 KB 44.85 KB 44.85 KB RN_OSS_PROD

react-art

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-art.development.js -2.7% -2.6% 535.8 KB 521.56 KB 115.29 KB 112.32 KB NODE_DEV
ReactART-dev.js -2.4% -2.3% 601.65 KB 587.2 KB 125.87 KB 122.94 KB FB_WWW_DEV
ReactART-prod.js 0.0% -0.0% 240.95 KB 240.95 KB 40.97 KB 40.97 KB FB_WWW_PROD
react-art.development.js -2.4% -2.2% 631.57 KB 616.5 KB 132.95 KB 130 KB UMD_DEV

react-test-renderer

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-test-renderer-shallow.production.min.js 0.0% 0.0% 12.91 KB 12.91 KB 3.93 KB 3.94 KB UMD_PROD
react-test-renderer.development.js -2.6% -2.6% 542.36 KB 528.13 KB 116.76 KB 113.75 KB NODE_DEV
ReactTestRenderer-dev.js -2.5% -2.5% 574.68 KB 560.3 KB 121.15 KB 118.16 KB FB_WWW_DEV
react-test-renderer.development.js -2.6% -2.6% 569.04 KB 553.98 KB 118.17 KB 115.13 KB UMD_DEV

react-dom

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-dom-test-utils.development.js 0.0% 0.0% 59.23 KB 59.23 KB 15.64 KB 15.64 KB UMD_DEV
ReactDOMTesting-profiling.js -0.0% -0.0% 403.86 KB 403.77 KB 73.47 KB 73.45 KB FB_WWW_PROFILING
react-dom-unstable-fizz.browser.development.js 0.0% +0.1% 3.34 KB 3.34 KB 1.26 KB 1.26 KB UMD_DEV
react-dom.profiling.min.js 0.0% 0.0% 122.02 KB 122.02 KB 38.32 KB 38.32 KB NODE_PROFILING
react-dom-server.node.development.js +0.1% +0.1% 127.53 KB 127.61 KB 34.09 KB 34.13 KB NODE_DEV
ReactDOMForked-dev.js -1.5% -1.4% 1002.92 KB 988.26 KB 222.78 KB 219.71 KB FB_WWW_DEV
ReactDOMForked-prod.js -2.6% -2.8% 422.61 KB 411.75 KB 76.68 KB 74.5 KB FB_WWW_PROD
react-dom.development.js -1.7% -1.5% 903.61 KB 888.53 KB 198.59 KB 195.63 KB UMD_DEV
ReactDOMForked-profiling.js -2.5% -2.8% 440.25 KB 429.43 KB 79.77 KB 77.51 KB FB_WWW_PROFILING
react-dom-server.browser.development.js +0.1% +0.1% 133.15 KB 133.23 KB 34.27 KB 34.32 KB UMD_DEV
react-dom.profiling.min.js 0.0% 0.0% 121.8 KB 121.8 KB 39.12 KB 39.12 KB UMD_PROFILING
ReactDOMTesting-dev.js +0.1% +0.1% 940.55 KB 941.55 KB 209.86 KB 210.09 KB FB_WWW_DEV
react-dom.development.js -1.7% -1.5% 860.04 KB 845.8 KB 196.17 KB 193.21 KB NODE_DEV
ReactDOMTesting-prod.js -0.0% -0.0% 403.86 KB 403.77 KB 73.47 KB 73.45 KB FB_WWW_PROD
react-dom-server.browser.development.js +0.1% +0.1% 126.32 KB 126.39 KB 33.84 KB 33.88 KB NODE_DEV
ReactDOM-dev.js -1.5% -1.4% 1002.92 KB 988.26 KB 222.78 KB 219.71 KB FB_WWW_DEV
ReactDOM-prod.js -2.6% -2.8% 422.61 KB 411.75 KB 76.68 KB 74.5 KB FB_WWW_PROD
ReactDOM-profiling.js -2.5% -2.8% 440.25 KB 429.43 KB 79.77 KB 77.51 KB FB_WWW_PROFILING
react-dom-test-utils.production.min.js 0.0% 0.0% 12.1 KB 12.1 KB 4.47 KB 4.47 KB NODE_PROD
react-dom-unstable-native-dependencies.development.js 0.0% 0.0% 54.71 KB 54.71 KB 14.13 KB 14.14 KB NODE_DEV

react-reconciler

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-reconciler.development.js -2.5% -2.4% 573.83 KB 559.6 KB 121.08 KB 118.13 KB NODE_DEV
react-reconciler-reflection.development.js +0.5% +0.9% 15.55 KB 15.62 KB 4.73 KB 4.77 KB NODE_DEV
react-reconciler-reflection.production.min.js 0.0% 🔺+0.1% 2.57 KB 2.57 KB 1.08 KB 1.08 KB NODE_PROD

Size changes (stable)

Generated by 🚫 dangerJS against bf41bd2

@sizebot
Copy link

sizebot commented Mar 28, 2020

Details of bundled changes.

Comparing: 5bd1bc2...bf41bd2

react-test-renderer

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-test-renderer.development.js -2.6% -2.6% 569.07 KB 554 KB 118.18 KB 115.14 KB UMD_DEV
react-test-renderer.development.js -2.6% -2.6% 542.39 KB 528.15 KB 116.77 KB 113.76 KB NODE_DEV
ReactTestRenderer-dev.js -2.5% -2.5% 574.7 KB 560.32 KB 121.16 KB 118.17 KB FB_WWW_DEV

react-dom

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-dom-server.browser.development.js +0.1% +0.1% 134.74 KB 134.82 KB 34.47 KB 34.52 KB UMD_DEV
react-dom.profiling.min.js 0.0% 0.0% 126.22 KB 126.22 KB 39.52 KB 39.53 KB NODE_PROFILING
react-dom-unstable-fizz.browser.development.js 0.0% +0.1% 3.35 KB 3.35 KB 1.27 KB 1.27 KB UMD_DEV
ReactDOM-dev.js +0.1% +0.2% 957.07 KB 958.35 KB 212.74 KB 213.07 KB FB_WWW_DEV
react-dom-unstable-fizz.browser.development.js 0.0% +0.1% 2.95 KB 2.95 KB 1.18 KB 1.18 KB NODE_DEV
react-dom-test-utils.development.js 0.0% 0.0% 59.24 KB 59.24 KB 15.65 KB 15.65 KB UMD_DEV
react-dom-test-utils.production.min.js 0.0% -0.0% 12.26 KB 12.26 KB 4.55 KB 4.55 KB UMD_PROD
ReactDOMTesting-dev.js +0.1% +0.2% 913.79 KB 915.03 KB 203.96 KB 204.29 KB FB_WWW_DEV
react-dom-test-utils.development.js 0.0% 0.0% 54.7 KB 54.7 KB 15.03 KB 15.04 KB NODE_DEV
react-dom-server.node.development.js +0.1% +0.1% 129.05 KB 129.12 KB 34.3 KB 34.35 KB NODE_DEV
react-dom-test-utils.production.min.js 0.0% 0.0% 12.12 KB 12.12 KB 4.48 KB 4.48 KB NODE_PROD
react-dom-server.node.production.min.js 0.0% 0.0% 20.49 KB 20.49 KB 7.52 KB 7.52 KB NODE_PROD
react-dom-server.browser.development.js +0.1% +0.1% 127.83 KB 127.9 KB 34.05 KB 34.09 KB NODE_DEV
react-dom-server.browser.production.min.js 0.0% 0.0% 20.08 KB 20.08 KB 7.38 KB 7.38 KB NODE_PROD
react-dom.development.js -1.6% -1.5% 933.4 KB 918.33 KB 203.81 KB 200.85 KB UMD_DEV
react-dom.production.min.js 0.0% 0.0% 122.09 KB 122.09 KB 39.04 KB 39.04 KB UMD_PROD
ReactDOMForked-dev.js +0.1% +0.2% 957.07 KB 958.35 KB 212.74 KB 213.07 KB FB_WWW_DEV
react-dom.profiling.min.js 0.0% 0.0% 125.92 KB 125.92 KB 40.28 KB 40.28 KB UMD_PROFILING
react-dom.development.js -1.6% -1.5% 888.6 KB 874.36 KB 201.33 KB 198.37 KB NODE_DEV
react-dom-unstable-native-dependencies.development.js 0.0% 0.0% 54.72 KB 54.72 KB 14.14 KB 14.14 KB NODE_DEV
react-dom-unstable-fizz.node.development.js 0.0% +0.1% 3.69 KB 3.69 KB 1.34 KB 1.34 KB NODE_DEV

react-art

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
ReactART-dev.js +0.2% +0.3% 573.58 KB 574.87 KB 120.2 KB 120.53 KB FB_WWW_DEV
react-art.development.js -2.3% -2.2% 651.84 KB 636.77 KB 136.62 KB 133.68 KB UMD_DEV
react-art.development.js -2.6% -2.5% 555.27 KB 541.03 KB 118.98 KB 116.01 KB NODE_DEV

react-native-renderer

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
ReactNativeRenderer-dev.js -2.2% -2.1% 652.37 KB 637.98 KB 140.72 KB 137.74 KB RN_FB_DEV
ReactFabric-dev.js -2.3% -2.2% 631.52 KB 617.07 KB 135.96 KB 132.94 KB RN_OSS_DEV
ReactFabric-dev.js -2.3% -2.2% 634.24 KB 619.85 KB 136.3 KB 133.32 KB RN_FB_DEV
ReactFabric-prod.js 0.0% 0.0% 258.85 KB 258.85 KB 44.88 KB 44.89 KB RN_FB_PROD
ReactNativeRenderer-dev.js -2.2% -2.2% 649.66 KB 635.21 KB 140.37 KB 137.34 KB RN_OSS_DEV
ReactNativeRenderer-profiling.js 0.0% 0.0% 278.51 KB 278.51 KB 48.59 KB 48.59 KB RN_OSS_PROFILING

react-reconciler

File Filesize Diff Gzip Diff Prev Size Current Size Prev Gzip Current Gzip ENV
react-reconciler-reflection.development.js +0.5% +0.9% 15.56 KB 15.64 KB 4.73 KB 4.77 KB NODE_DEV
react-reconciler-reflection.production.min.js 0.0% 🔺+0.1% 2.58 KB 2.58 KB 1.09 KB 1.09 KB NODE_PROD
react-reconciler.development.js -2.4% -2.4% 595.64 KB 581.4 KB 125.29 KB 122.32 KB NODE_DEV

Size changes (experimental)

Generated by 🚫 dangerJS against bf41bd2

@gaearon gaearon changed the title Remove Calls to User Timing API RFC: Remove Calls to User Timing API Mar 28, 2020
target._debugID = source._debugID;
target._debugIsCurrentlyTiming = source._debugIsCurrentlyTiming;
}
target._debugID = source._debugID;
Copy link
Contributor

@bvaughn bvaughn Mar 28, 2020

Choose a reason for hiding this comment

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

This should be in an if (__DEV__) block, I think?

Actually I think the few lines below it should be as well.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This whole function is DEV-only so I'm not sure this is necessary.

Copy link
Contributor

Choose a reason for hiding this comment

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

I realize the function is named assignFiberPropertiesInDEV but it's not actually gated anywhere to be DEV only.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It's gated at the usage site. But I agree it would make sense to wrap its body too.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, we usually gate in both places I think.

Not new to this PR, just something I noticed while looking at the code changes.

Copy link
Contributor

@bvaughn bvaughn left a comment

Choose a reason for hiding this comment

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

🎉

@gaearon gaearon changed the title RFC: Remove Calls to User Timing API Remove Calls to User Timing API Mar 30, 2020
@gaearon
Copy link
Collaborator Author

gaearon commented Mar 30, 2020

Internal blocker removed in D20720332.

@gaearon
Copy link
Collaborator Author

gaearon commented Mar 30, 2020

tldr: this is unfortunate but if we're going to re-add this, we'll need to do it differently and probably only support very recent browsers (Level 3 spec).

@gaearon gaearon merged commit bf30e37 into facebook:master Mar 30, 2020
@gaearon gaearon deleted the no-perf branch March 30, 2020 23:30
@julienw
Copy link

julienw commented Nov 20, 2020

Hey,
we just upgraded to React v17 in our project (the Firefox Profiler) and that's how I realized the UserTiming markers have been removed.

I know the ship has sailed for long on this, but I wanted to give a feedback on the removal of the user timing in the context of our project.

These user timing markers were super useful inside the Firefox Profiler, because we could see them on the same interface than other information (especially javascript sampling with stacks), and we could clearly see that some component took a long time to render, with its children.

Here are a few examples:
https://share.firefox.dev/3pWM1MK
https://share.firefox.dev/3nI34Qw

So the exactness of the timings wasn't as important as having a general idea of what's going on, before digging further.

I'm not so sure that using the standalone React Profiler is an improvement on that.
I'll look into using the new programmatic <Profiler> component that looks definitely interesting, and see if we can recreate the previous feature. Maybe that does exist elsewhere already?

Thanks

@bvaughn
Copy link
Contributor

bvaughn commented Nov 20, 2020

Hey @julienw 👋

I'll look into using the new programmatic <Profiler> component that looks definitely interesting, and see if we can recreate the previous feature.

You can't recreate the user timing marks using <Profiler> (unless you tried to literally wrap every component in your app– which I wouldn't advise doing). The React DevTools profiling tool can do this because it has deep hooks into React itself.

I'm not so sure that using the standalone React Profiler is an improvement on that.

Can you elaborate on what pitfalls the React DevTools profiler has that makes it seem less useful to you? I'd love to learn more.

Also I'm wondering if you've seen this side work we've been doing on a new profiling tool? It doesn't yet support parsing Firefox profiles, but that could be added 😁 Especially if we had a little help 😉

Would you (or someone else on your team) be interested in hopping on a video chat about this sometime? Might be useful for us to each have a better sense of what each other is working on and how we might be able to help each other.

@bvaughn
Copy link
Contributor

bvaughn commented Nov 20, 2020

I'll look into using the new programmatic <Profiler> component that looks definitely interesting, and see if we can recreate the previous feature.

You can't recreate the user timing marks using <Profiler> (unless you tried to literally wrap every component in your app– which I wouldn't advise doing). The React DevTools profiling tool can do this because it has deep hooks into React itself.

A quick note about this though: If you add selective <Profiler> wrappers to parts of your application, and then use the id, renderTime, and commitTime params passed to their callbacks, you can attribute parts of your flame graph in a way that might still be very helpful using the User Timing API level 3. I was just thinking about this myself the other day:

image

image

@julienw
Copy link

julienw commented Nov 20, 2020

Thanks for the quick answer!

You can't recreate the user timing marks using (unless you tried to literally wrap every component in your app– which I wouldn't advise doing).

Ah, thanks for telling me this. I initially thought we could get all updates by using a top-level <Profiler> component.
Maybe wrapping every component in a special mode (with a specific parameter, or enabling it from the console) would work :-)

Can you elaborate on what pitfalls the React DevTools profiler has that makes it seem less useful to you? I'd love to learn more.

While analyzing a profile, the first step is to focus on one interesting part. There are various ways to do this, but looking at the React markers is one common way when we work on a performance issue in a react application: we can double click on one of the markers, or select a group of markers, and only then move to another panel (probably the flame graph) to further analyze the performance issue.

Being a standalone profiler, with the Devtools profiler we can't do this easy dance of using it to focus on one specific part of a profile. But I admit I haven't been using it for some weeks now, so I may have missed new stuff.

Also I'm wondering if you've seen this side work we've been doing on a new profiling tool? It doesn't yet support parsing Firefox profiles, but that could be added. Especially if we had a little help wink

Ah ah I've seen it mentioned but didn't use it really yet :-)

Would you (or someone else on your team) be interested in hopping on a video chat about this sometime? Might be useful for us to each have a better sense of what each other is working on and how we might be able to help each other.

I'll talk about that internally, I believe that would be useful indeed! Helping make React apps faster is a clear goal for us :-)

@bvaughn
Copy link
Contributor

bvaughn commented Nov 20, 2020

I initially thought we could get all updates by using a top-level <Profiler> component.

This would give you aggregate statistics for all components within the Profiler's subtree, but it wouldn't be broken down by component like it is in the flamegraph.

While analyzing a profile...

Not sure if I understand the work flow you're describing, but it sounds like maybe you start by scanning some zoomed-out version of the flame graph and then focus in on any of the parts that looks slow and use the user timing markers to see if it's related to React? The React Profiler can help show you what the slowest part(s) of your app are from its perspective, but admittedly it misses some of the surrounding context (e.g. other JS and how slow it is relative, or even how much time is spent by React itself outside of your components). This is one of the reasons I would love to see us get more hooks into the native Performance panel 😄

Let me know if/when you or anyone else from Moz wants to chat about this stuff. I'm always happy to make the time. 😄

@julienw
Copy link

julienw commented Nov 20, 2020

I was analyzing another problem today, and thought this could be another good example of how we were using the React Markers.
After zooming in to the right location, here I am with this stack chart:
image

With only the JS function names, everything is very generic. The React UserTiming markers were helping to understand what was going on.
... of course, our lack of sourcemap support (in our tool, I mean) doesn't help :-)

@bvaughn
Copy link
Contributor

bvaughn commented Nov 20, 2020

React's implementation doesn't match most people's mental models for how components a React tree gets rendered. For example, it's iterative b'c of the requirement to yield and resume frequently without a lot of overhead. We may also render components in a seeming bizarre order because of APIs like Suspense. I think the React DevTools Profiler flame chart (which gets stitched back together in a way that's easy to think about and understand) is pretty useful in that regard, in a way that user timing markers just couldn't do.

@JPNZ4
Copy link

JPNZ4 commented Feb 4, 2021

Hi,

I recently upgraded to v17.0. I really miss this feature, I used it while also displaying a redux dispatched action. I found this very useful to identify issues with unnecessary or duplicate renders as I would get a nice overview of what action I dispatched and all the components that rendered under it. The inaccurate timings were not an issue for me as once I identified an area that needed some work I would use other tools to drill into the problem.

Now I don't have a nice way to replicate this view. I can still see my dispatched timings and I can profile individual renders with the react profiler but I miss having a way to see what action caused a group of renders. Is there any other way to achieve this?

@bvaughn
Copy link
Contributor

bvaughn commented Feb 8, 2021

@JPNZ4 No. There is no current alternative for the User Timing marks that used to be in React DEV builds. Typically we suggest using the React DevTools Profiler instead but for your use case that wouldn't really be relevant.

We have some ongoing efforts on building a new profiling tool that would be similar to the user marks, which you can read about (and even beta test) here but I don't expect we'll release this in a more stable format for at least a few months because of competing priorities.

This was referenced Mar 15, 2021
@eltonio450
Copy link

Hello everyone,

I feel soooo late on this, but after digging for days, I am glad I found this thread :)

I don't know if it is the best place for this, but: User Timing API was not the best solution indeed, but allowed to access data programmatically. This is super powerful to optimize/supervise performance "in real condition" (ex: sampling random sessions, isolating slow renders, etc.)

From my understanding, the DevTools now has some kind of direct access to React, which is difficult to reproduce from an external package, am I correct?

Did anyone find an option to observe performance programmatically and "globally"? The options seem to be:

  • put the Profiler component everywhere. Maybe by using a babel plugin or something like that? Might be slow?
  • monkey patch React to inject some kind of hooks (difficult)
  • reproduce ReactDevTools tracking mechanism (hard to follow?

Really interesting topic!

Thank you!

@ClementCastel
Copy link

Hello, I am facing the same problem currently. I would like to be able to observe performance of all my components programmically. Especially being able to track the rerenders of components that haven't changed (what printWasted() of the old Perf addon was able to do), get how many instances of a component there is, etc...
I am very interested to know how your research went and if you have found interesting ressources.
Thank you

@eltonio450
Copy link

I deep dived to reproduce ReactDevTools tracking mechanism but had to give up as it was really hard to follow unfortunately

might give another shot later :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed React Core Team Opened by a member of the React Core Team
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants