Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Profiler RFC#51

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
bvaughn merged 12 commits intoreactjs:masterfrombvaughn:profiler
Jul 25, 2019
Merged

Profiler RFC#51

bvaughn merged 12 commits intoreactjs:masterfrombvaughn:profiler
Jul 25, 2019

Conversation

@bvaughn
Copy link
Collaborator

@bvaughnbvaughn commentedMay 22, 2018
edited
Loading

View formatted RFC


Feedback is welcome!

  • Would you use these timings?
  • If not (or if so) is there something else we could add to make it more useful to you?
  • Do you have ideas for abstractions (or visualizations) we could build on top of this to make it more useful and/or beginner friendly?

Related PRs

TrySound, brunolemos, hnordt, fbartho, rhinodavid, callmeberzerker, paularmstrong, divyanshu013, ConAntonakos, puemos, and 68 more reacted with thumbs up emojifakenickels, selbekk, paramsinghvc, cody-elhard, TheFacto, sujithnath, and 0xdevalias reacted with heart emoji
@fbartho
Copy link

I certainly would use these timings / this component in my team's app. Identifying which "screen" suffers the most would be very valuable.

Is there a model in this for profiling"time until interactive" - networkTime -- This way we can see the fully loaded data, and optimize the React Render tree directly?

Also valuable: if it could automatically bubble up which sub-component is most at fault, or the number of re-renders of subcomponents. This way we can identify data misuse that leads to repeat renders.

y13uc130 and vincenzocaruso reacted with thumbs up emoji3gzon, AdirAmsalem, AlexBuitrago, and KyleMit reacted with heart emoji

@tizmagik
Copy link

Would it be possible to detect/report on “useless” or unnecessary updates?

nimrossum, DmitriyWebDev, ls-miles-rostami, gabrielAnzaldo, pbondoer, walshie4, vincenzocaruso, michaelkirschbaum, and sarthakbaweja148 reacted with thumbs up emoji

@bvaughn
Copy link
CollaboratorAuthor

bvaughn commentedMay 23, 2018
edited
Loading

Thank you both for your feedback 😄

Is there a model in this for profiling "time until interactive" - networkTime -- This way we can see the fully loaded data, and optimize the React Render tree directly?

I'm sorry, but I'm not sure I understand what you're suggesting. Could you elaborate?

Also valuable: if it could automatically bubble up which sub-component is most at fault, or the number of re-renders of subcomponents. This way we can identify data misuse that leads to repeat renders.

I think this might be better handled by DevTools. (I have an idea that I hope to prototype for how the newProfiler might integrate with DevTools to power some local visualizations/graphs of an application. More to come soon...)

Something like the number of re-renders seems easier to detect and handle locally, because it's easier to reproduce / more predictable (regardless of system specs). On the other hand, timing is often impacted by hardware capabilities and browser/versions, and may be difficult for devs to get an accurate idea about from their (generally high-end) machines.

Also, timing is probably the most important "cost" of rendering. If a component re-renders unnecessarily, but it's super fast- is it actually that important? On the other hand, if it's slow each time the app renders- regardless of whether the render was "useless" or not, it should probably be looked into.

That being said, I haven't thought a lot about non timing aspects of this. Maybe I'm overlooking something. Let's see what others think about it. 😄

Would it be possible to detect/report on “useless” or unnecessary updates?

Something likemaicki/why-did-you-update?

To be honest, I haven't considered this much. Initially, I think it might be tricky, because of e.g. inline functions for event handlers. (These might interact with the DOM even though it was unnecessary. Seems hard for React to detect without adding overhead of something like a per-renderer property whitelist, etc.)

Definitely seems useful. Although similar to the number of renders/re-renders, it seems more predictable / easier to reproduce locally than timing- so maybe this is something that belongs in DEV mode only, rather than a profiling build?

@gaearon
Copy link
Member

I think the notion of “useless” never made a lot of sense. It was a handy heuristic in some cases but it both failed to identify some “less useful” cases and incorrectly tagged “useful” updates as wasted.

Now, I know a lot of people want to see this heuristic come back in some form. I think what we really want there is a scale rather than a yes/no flag. If a big tree was reconciled and it took a lot of time, but the result was just a couple of DOM changes, it’s still worth looking into, even though it’s not completely “wasted”. Similarly, a fast re-render of a few components that didn’t lead to DOM updates isn’t necessarily useful to act upon if it’s fast.

So I think what we want is a scale of how much the update cost (in time) vs how much it affected the output (host effects, lifecycles). And we’d like to see the updates (as setState calls?) that have the worst ratio on that scale.

I don’t know if it needs to be a part of this RFC. But that’s how I see “wasted” heuristic in the future if we add it again.

Does that make sense?

paularmstrong, tizmagik, augbog, baptistemanson, vineandfork, vinnymac, DmitriyWebDev, TroySchmidt, ahmedam66, housseindjirdeh, and 2 more reacted with thumbs up emoji

@paularmstrong
Copy link

paularmstrong commentedMay 23, 2018
edited
Loading

This looks really great!

Would you use these timings?

Absolutely yes. We have a timing HOC at Twitter and it's not going to work once React hits v17.0.0 and deprecates some things. (it's rudimentary, but it gets us enough information to alert on critical regressions)

As for this particular RFC:

id attribute: I'm a bit unclear on this, as the RFC isn't specific...

Does this have to be unique? If I were to use the sameid on many instances, e.g. in a timeline of Tweets,<Profiler onRender={this._handleProfilerRender}><Tweet /></Profiler>, would_handleProfilerRender be called for each, or once per render cycle for all of those with the sameid?

The way it looks with the definition forbaseTime is that I will_handleProfilerRender will be called only once with the most recent time it was called.

3gzon reacted with laugh emoji

@fbartho
Copy link

@bvaughn in reply to your response: yes I totally agree that some of my requests might live better in the DevTools. -- I'm also considering this from the concept of a React-Native platform as my first target, I'm not sure that redirects your comments, but maybe that gives you more context?

In regards to your question re my comment about "time-till-interactive" I'm trying to optimize for performance when many of the components are embedded in GraphQL Query components from Apollo. It's want to have more insight into how long it takes for my UI to "settle" which is a time-diff between componentDidMount and the last re-render after data comes back. I admit I'm a bit confused as to how to best profile & track which parts of my component tree need love.

@alvaropinot
Copy link

Thanks for sharing, I will definitely use it.

I can think about the following ideas:

  • Add ageneric implementation for theonRender method that might provide a mechanism for beginners to see perf results with 0 setup. Maybe a separate package can do this. This could be the seed of a profile reporter that could be integrated within react dev tools.
  • Considertoggling the component behaviour on/off dependending on a prop. This might allow disabling it in prod or disabling it when devtools are not open, or within any scenario where the performance impact of profiling might be negative.
  • It can be specially interesting forwrapping components in a performance/TDD approach where min metrics should be fullfilled to obtain a passing perf test.

Again thanks for sharing, hope those 👆help 😁

baransu, miraage, MQuy, and vincenzocaruso reacted with thumbs up emoji

@miraage
Copy link

miraage commentedMay 23, 2018
edited
Loading

Opinion: it would be amazing to have an option to toggle<Profiler> via React DevTools or a browser extension.

I think it might be useful to avoid using "hacks" (e.g. global variables, global functions) in production.

E.g. you push potential bottlenecks wrapped into a disabled<Profiler> (so your site's users see no difference), while you can do your measurements by your own.

// EDIT

Oh, basically I described 2nd idea from@alvaropinot.
Next time I'll read comments first. :)

rromanovsky, alvaropinot, and refun07 reacted with thumbs up emojialvaropinot reacted with laugh emoji

@bvaughn
Copy link
CollaboratorAuthor

bvaughn commentedMay 23, 2018
edited
Loading

@paularmstrong Thanks!

id attribute: I'm a bit unclear on this, as the RFC isn't specific...
Does this have to be unique? If I were to use the same id on many instances...would _handleProfilerRender be called for each, or once per render cycle for all of those with the same id?

Callbacks will always be called once perProfiler (assuming thatProfiler has at least one child that rendered).

The ID is for your benefit only. If you are using a single, centralized logging function- the ID can help identify whichProfiler (which tree) it is referring to. It does not have to be unique. React doesn't use it or check it in any way, just passes it through.

The way it looks with the definition forbaseTime is that I will_handleProfilerRender will be called only once with the most recent time it was called.

I'm not sure what you're saying. Clarify?


@fbartho

yes I totally agree that some of my requests might live better in the DevTools. -- I'm also considering this from the concept of a React-Native platform as my first target, I'm not sure that redirects your comments, but maybe that gives you more context?

React Native support is a central focus for this new component, and will also be a central focus for the DevTools work I'll be doing soon. We realize that RN is currently a bit harder to profile than React DOM.

In regards to your question re my comment about "time-till-interactive" I'm trying to optimize for performance when many of the components are embedded in GraphQL Query components from Apollo. It's want to have more insight into how long it takes for my UI to "settle" which is a time-diff between componentDidMount and the last re-render after data comes back.

Seems like you should be able to infer this based on when your callback is called? The first time it is called for a tree, thephase will be "mount" (so that's your starting point) and then subsequent calls (while it "settles"m as you put it) will have aphase of "update". You can use thecommitTime of these calls to compute your own delta.


@alvaropinot

Add a generic implementation for the onRender method that might provide a mechanism for beginners to see perf results with 0 setup.

This is where React DevTools fits in! Can't wait to show you what Sebastian and I have been brainstorming here. 😄

Consider toggling the component behaviour on/off dependending on a prop. This might allow disabling it in prod or disabling it when devtools are not open, or within any scenario where the performance impact of profiling might be negative.

You could do this via a HOC (if you wanted). The way we intend for this to work by default though will be: ON for development and profiling bundles, OFF for production. (It doesn't really matter if it's always on for dev mode, since the perf impact is minimal. You can switch which production bundle of React is used- regular or profiling- to turn it off for production mode.)


@miraage

Opinion: it would be amazing to have an option to toggle via React DevTools or a browser extension.

Yes! This is planned! 😁 Will share something soon.

alvaropinot reacted with thumbs up emojimiraage, rromanovsky, baransu, alvaropinot, and walshie4 reacted with hooray emojialvaropinot reacted with heart emoji

@jamesreggio
Copy link

This issuper exciting — especially that React Native support will be included from the start.

I have a couple questions/suggestions:

  1. Just to confirm, an update to any descendent of a Profiler component (not just its immediate descendants) will trigger theonRender callback, correct?

  2. It would be nice to be able to correlateonRender callbacks on separate Profiler components that fire during the same rendering transaction. For example, if a Redux dispatch causes an update in two disjoint subtrees, each with a separate Profiler, I'd like to be able to correlate the twoonRender callbacks to the dispatch. Perhaps you could include an auto-incrementing transaction ID in the callback data?

  3. How does this behave if a subtree that contains a Profiler gets jettisoned during the dispatching of an exception? Suspense is going to make this pattern more common, and I may still want to measure the amount of time spent on anupdate phase that ultimately results in the unmounting of a subtree. The example I'm thinking of looks something like this:

<Timeout>{didTimeout=>didTimeout ?<Spinner/> :(<Lotsofothercomponentsonthisscreen><Profiler><AsyncResource/></Profiler></Others>)}</Timeout>

In this case, a cache miss on AsyncResource is going to cause everything under Timeout to unmount, including the Profiler. It'd still be interesting to be able to profile the cost of the mount/update phase that led to the immediate unmounting.

(I'm not an expert on Suspense, so please forgive me if this use case is unclear. I'd be happy to clarify.)

baseTime: number,
startTime: number,
commitTime: number
): void {

Choose a reason for hiding this comment

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

Why not pass all of this as a single object so people can pick out the keys they need?

Copy link
CollaboratorAuthor

Choose a reason for hiding this comment

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

Reasonable question!

I'd say the reasons are that I'm following precedent (we don't pass named parameters anywhere else that I can think of off the top of my head) and avoiding allocating a wrapper Object during commit.

I'd be interested to hear what others think about this aspect.

Choose a reason for hiding this comment

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

I'd vote for an object, despite the fact that it breaks with existing React API precedent.

The order of these timing arguments is going to be tough to memorize, and I can imagine only being interested in a subset of them. Using an object also enables you to add additional timing data down the road.

I'd view it as somewhat analogous to an event object, which has a variety of keys, only some of which are of interest for any given listener.

AjayPoshak and alvaropinot reacted with thumbs up emoji
Copy link
Member

Choose a reason for hiding this comment

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

Why would you need to memorize it? I imagine you'd only use Profiler in a few places in the app, and each time could consult the docs.

The need to avoid allocations is pretty important because adding GC pressure can skew the profiling results.

paularmstrong, TryingToImprove, omninonsense, and vineandfork reacted with thumbs up emoji
Copy link
CollaboratorAuthor

Choose a reason for hiding this comment

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

Even if you useProfiler in more than one place, the callback you pass it is likely shared- (this is why theid parameter exists)- so you would only need to write these params (in the correct order) in a single place.

paularmstrong and gaearon reacted with thumbs up emoji
Copy link
CollaboratorAuthor

@bvaughnbvaughnMay 23, 2018
edited
Loading

Choose a reason for hiding this comment

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

Yup, this concern makes sense. And I agree that we wouldn't be allocating too many new objects for this, because it would only be one perProfiler per commit. I was just sharing rationale for why it is currently the way it is.

jamesreggio and fanderzon reacted with thumbs up emoji

Choose a reason for hiding this comment

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

Just my personal opinion here, but an object looks good from my point of view as long functions with more that 2/3 args are always hard to remember, you tend to start addingnull for the values that you might not want to use, I'm looking at youJSON.stringify(foo, null, 2) 😅 , you also need to remember the order and it's harder to refactor as you impact anyone already using that order.

Plus with the actual syntax for destructuring the function signature looks pretty much the same but with curly braces 😁, the best of two worlds!

onRenderCallback({ id, phase, actualTime, baseTime, startTime, commitTime})

vs

onRenderCallback(id,phase,actualTime,baseTime,startTime,commitTime)

TryingToImprove, jamesreggio, and TroySchmidt reacted with thumbs up emoji

Choose a reason for hiding this comment

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

Now that the Profiling API is out in the 16.4.1 release, I assume you decided to take no action on this?

Copy link
CollaboratorAuthor

Choose a reason for hiding this comment

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

Theunstable_Profiler component was introduced in 16.4.0. The only thing that's new in 16.4.1 is a production+profiling build.

Unstable APIs can change. We haven't decided one way or another. This is kind of an open thread for discussion.

jamesreggio reacted with thumbs up emoji
Copy link
CollaboratorAuthor

Choose a reason for hiding this comment

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

Just circling back on this particular thread. Sebastian and I chatted about this yesterday, and we've decided to avoid named parameters because the overhead of the wrapper objects (however small each individual one is) will add up in larger applications.

@bvaughn
Copy link
CollaboratorAuthor

@jamesreggio

Just to confirm, an update to any descendent of a Profiler component (not just its immediate descendants) will trigger theonRender callback, correct?

Correct.

It would be nice to be able to correlateonRender callbacks on separate Profiler components that fire during the same rendering transaction. For example, if a Redux dispatch causes an update in two disjoint subtrees, each with a separate Profiler, I'd like to be able to correlate the two onRender callbacks to the dispatch.

ThecommitTime parameter can be used for this.

How does this behave if a subtree that contains a Profiler gets jettisoned during the dispatching of an exception?

In the scenario you describe, since the components underneath of theTimeout component would not be committed, theProfiler inside of it would not be called. You could measure the "cost" of this by wrapping aProfiler around theTimeout component though, I believe.

jamesreggio reacted with thumbs up emoji

borsbot referenced this pull request in mythmon/corsica-tree-statusMay 24, 2018
20: Update react monorepo to v16.4.0 r=renovate[bot] a=renovate[bot]This Pull Request renovates the package group "react monorepo".-   [react-dom](https://github.com/facebook/react) (`dependencies`): from `16.3.2` to `16.4.0`-   [react](https://github.com/facebook/react) (`dependencies`): from `16.3.2` to `16.4.0`# Release Notes<details><summary>facebook/react</summary>### [`v16.4.0`](https://github.com/facebook/react/blob/master/CHANGELOG.md#&#8203;1640-May-23-2018)[Compare Source](facebook/react@8e5f12c...v16.4.0)##### React* Add a new [experimental](`https://github.com/reactjs/rfcs/pull/51`) `React.unstable_Profiler` component for measuring performance. ([@&#8203;bvaughn] in [#&#8203;12745](`https://github.com/facebook/react/pull/12745`))##### React DOM* Add support for the Pointer Events specification. ([@&#8203;philipp-spiess] in [#&#8203;12507](`https://github.com/facebook/react/pull/12507`))* Properly call `getDerivedStateFromProps()` regardless of the reason for re-rendering. ([@&#8203;acdlite] in [#&#8203;12600](`https://github.com/facebook/react/pull/12600`) and [#&#8203;12802](`https://github.com/facebook/react/pull/12802`))* Fix a bug that prevented context propagation in some cases. ([@&#8203;gaearon] in [#&#8203;12708](`https://github.com/facebook/react/pull/12708`))* Fix re-rendering of components using `forwardRef()` on a deeper `setState()`. ([@&#8203;gaearon] in [#&#8203;12690](`https://github.com/facebook/react/pull/12690`))* Fix some attributes incorrectly getting removed from custom element nodes. ([@&#8203;airamrguez] in [#&#8203;12702](`https://github.com/facebook/react/pull/12702`))* Fix context providers to not bail out on children if there's a legacy context provider above. ([@&#8203;gaearon] in [#&#8203;12586](`https://github.com/facebook/react/pull/12586`))* Add the ability to specify `propTypes` on a context provider component. ([@&#8203;nicolevy] in [#&#8203;12658](`https://github.com/facebook/react/pull/12658`))* Fix a false positive warning when using `react-lifecycles-compat` in `<StrictMode>`. ([@&#8203;bvaughn] in [#&#8203;12644](`https://github.com/facebook/react/pull/12644`))* Warn when the `forwardRef()` render function has `propTypes` or `defaultProps`. ([@&#8203;bvaughn] in [#&#8203;12644](`https://github.com/facebook/react/pull/12644`))* Improve how `forwardRef()` and context consumers are displayed in the component stack. ([@&#8203;sophiebits] in [#&#8203;12777](`https://github.com/facebook/react/pull/12777`))* Change internal event names. This can break third-party packages that rely on React internals in unsupported ways. ([@&#8203;philipp-spiess] in [#&#8203;12629](`https://github.com/facebook/react/pull/12629`))##### React Test Renderer* Fix the `getDerivedStateFromProps()` support to match the new React DOM behavior. ([@&#8203;koba04] in [#&#8203;12676](`https://github.com/facebook/react/pull/12676`))* Fix a `testInstance.parent` crash when the parent is a fragment or another special node. ([@&#8203;gaearon] in [#&#8203;12813](`https://github.com/facebook/react/pull/12813`))* `forwardRef()` components are now discoverable by the test renderer traversal methods. ([@&#8203;gaearon] in [#&#8203;12725](`https://github.com/facebook/react/pull/12725`))* Shallow renderer now ignores `setState()` updaters that return `null` or `undefined`. ([@&#8203;koba04] in [#&#8203;12756](`https://github.com/facebook/react/pull/12756`))##### React ART* Fix reading context provided from the tree managed by React DOM. ([@&#8203;acdlite] in [#&#8203;12779](`https://github.com/facebook/react/pull/12779`))##### React Call Return (Experimental)* This experiment was deleted because it was affecting the bundle size and the API wasn't good enough. It's likely to come back in the future in some other form. ([@&#8203;gaearon] in [#&#8203;12820](`https://github.com/facebook/react/pull/12820`))##### React Reconciler (Experimental)* The [new host config shape](https://github.com/facebook/react/blob/c601f7a64640290af85c9f0e33c78480656b46bc/packages/react-noop-renderer/src/createReactNoop.js#L82-L285) is flat and doesn't use nested objects. ([@&#8203;gaearon] in [#&#8203;12792](`https://github.com/facebook/react/pull/12792`))---</details>---This PR has been generated by [Renovate Bot](https://renovatebot.com).Co-authored-by: Renovate Bot <bot@renovateapp.com>
borsbot referenced this pull request in mozilla/delivery-consoleMay 24, 2018
164: Update react monorepo to v16.4.0 r=rehandalal a=renovate[bot]This Pull Request renovates the package group "react monorepo".-   [react-dom](https://github.com/facebook/react) (`dependencies`): from `16.3.2` to `16.4.0`-   [react](https://github.com/facebook/react) (`dependencies`): from `16.3.2` to `16.4.0`# Release Notes<details><summary>facebook/react</summary>### [`v16.4.0`](https://github.com/facebook/react/blob/master/CHANGELOG.md#&#8203;1640-May-23-2018)[Compare Source](facebook/react@8e5f12c...v16.4.0)##### React* Add a new [experimental](`https://github.com/reactjs/rfcs/pull/51`) `React.unstable_Profiler` component for measuring performance. ([@&#8203;bvaughn] in [#&#8203;12745](`https://github.com/facebook/react/pull/12745`))##### React DOM* Add support for the Pointer Events specification. ([@&#8203;philipp-spiess] in [#&#8203;12507](`https://github.com/facebook/react/pull/12507`))* Properly call `getDerivedStateFromProps()` regardless of the reason for re-rendering. ([@&#8203;acdlite] in [#&#8203;12600](`https://github.com/facebook/react/pull/12600`) and [#&#8203;12802](`https://github.com/facebook/react/pull/12802`))* Fix a bug that prevented context propagation in some cases. ([@&#8203;gaearon] in [#&#8203;12708](`https://github.com/facebook/react/pull/12708`))* Fix re-rendering of components using `forwardRef()` on a deeper `setState()`. ([@&#8203;gaearon] in [#&#8203;12690](`https://github.com/facebook/react/pull/12690`))* Fix some attributes incorrectly getting removed from custom element nodes. ([@&#8203;airamrguez] in [#&#8203;12702](`https://github.com/facebook/react/pull/12702`))* Fix context providers to not bail out on children if there's a legacy context provider above. ([@&#8203;gaearon] in [#&#8203;12586](`https://github.com/facebook/react/pull/12586`))* Add the ability to specify `propTypes` on a context provider component. ([@&#8203;nicolevy] in [#&#8203;12658](`https://github.com/facebook/react/pull/12658`))* Fix a false positive warning when using `react-lifecycles-compat` in `<StrictMode>`. ([@&#8203;bvaughn] in [#&#8203;12644](`https://github.com/facebook/react/pull/12644`))* Warn when the `forwardRef()` render function has `propTypes` or `defaultProps`. ([@&#8203;bvaughn] in [#&#8203;12644](`https://github.com/facebook/react/pull/12644`))* Improve how `forwardRef()` and context consumers are displayed in the component stack. ([@&#8203;sophiebits] in [#&#8203;12777](`https://github.com/facebook/react/pull/12777`))* Change internal event names. This can break third-party packages that rely on React internals in unsupported ways. ([@&#8203;philipp-spiess] in [#&#8203;12629](`https://github.com/facebook/react/pull/12629`))##### React Test Renderer* Fix the `getDerivedStateFromProps()` support to match the new React DOM behavior. ([@&#8203;koba04] in [#&#8203;12676](`https://github.com/facebook/react/pull/12676`))* Fix a `testInstance.parent` crash when the parent is a fragment or another special node. ([@&#8203;gaearon] in [#&#8203;12813](`https://github.com/facebook/react/pull/12813`))* `forwardRef()` components are now discoverable by the test renderer traversal methods. ([@&#8203;gaearon] in [#&#8203;12725](`https://github.com/facebook/react/pull/12725`))* Shallow renderer now ignores `setState()` updaters that return `null` or `undefined`. ([@&#8203;koba04] in [#&#8203;12756](`https://github.com/facebook/react/pull/12756`))##### React ART* Fix reading context provided from the tree managed by React DOM. ([@&#8203;acdlite] in [#&#8203;12779](`https://github.com/facebook/react/pull/12779`))##### React Call Return (Experimental)* This experiment was deleted because it was affecting the bundle size and the API wasn't good enough. It's likely to come back in the future in some other form. ([@&#8203;gaearon] in [#&#8203;12820](`https://github.com/facebook/react/pull/12820`))##### React Reconciler (Experimental)* The [new host config shape](https://github.com/facebook/react/blob/c601f7a64640290af85c9f0e33c78480656b46bc/packages/react-noop-renderer/src/createReactNoop.js#L82-L285) is flat and doesn't use nested objects. ([@&#8203;gaearon] in [#&#8203;12792](`https://github.com/facebook/react/pull/12792`))---</details>---This PR has been generated by [Renovate Bot](https://renovatebot.com).Co-authored-by: Renovate Bot <bot@renovateapp.com>
@bvaughn
Copy link
CollaboratorAuthor

So I guess I'm generally advocating for fallback support or customizable measurement mechanisms instead of relying exclusively on newer (non-universal) browser APIs.

I don't understand what you mean with regard to this proposal. The profiler API does not use thePerformanceObserver API. It usesperformance.now()if available and falls back toDate.now() otherwise– just as React's scheduler does.

@jrnail23
Copy link

@bvaughn, if that's the case, then great! I may be getting my tools mixed up here -- sorry for any misunderstanding.

@bvaughn
Copy link
CollaboratorAuthor

No worries 😄

@lixiong-intelex
Copy link

lixiong-intelex commentedSep 7, 2018
edited
Loading

Hi@bvaughn , a dumb question, will I be able to use the new Profile feature after I upgrade React to 16.5.0 and React Dev Tools to 3.3.2?

@bvaughn
Copy link
CollaboratorAuthor

Yes, the profiler plugin will work with 16.5– assuming you're either running in dev mode or using the profiling build (e.g.import ReactDOM from 'react-dom/profiling')

@jrnail23
Copy link

@lixiong-intelex, I also had to update react-dom to v16.5.0 to get the profiling tab to show.

@lixiong-intelex
Copy link

@jrnail23 that's what I found out as well. Thanks!

jrnail23 reacted with hooray emoji

@bvaughn
Copy link
CollaboratorAuthor

Ah, I see the confusion.react andreact-dom should always use the same versions. When you asked about upgrading "react" I assumed you meant both. :)

ljharb reacted with thumbs up emoji

@swyxio
Copy link

is this rfc settled?

@bvaughn
Copy link
CollaboratorAuthor

Probably. We'll likely close it in the next couple of weeks, when we remove the "unstable_" prefix.

Why do you ask?

@swyxio
Copy link

was just browsing rfc's and saw this was still open thats all. thought it was stale. congrats on shipping!

@lippyDesign
Copy link

lippyDesign commentedDec 14, 2018
edited by bvaughn
Loading

Can someone explain to me how wrap works with async calls? I'm trying to measure how long it takes to make api request and render:

importReact,{unstable_ProfilerasProfiler}from"react";import{unstable_traceastrace,unstable_wrapaswrap}from"scheduler/tracing";importaxiosfrom"axios";importListfrom"./List";classAppextendsReact.Component{state={count:0,data:null};componentDidMount(){this.fetchData();}logProfile=(id,phase,actualTime,baseTime,startTime,commitTime,interactions)=>{console.log("--------- logProfile fired -----------");console.log(`${id}'s${phase.toUpperCase()} phase:`);console.log(`Actual time:${actualTime} ms`);console.log(`Base time:${baseTime} ms`);console.log(`Start time (since component mounted):${startTime} ms`);console.log(`Commit time (since component mounted):${commitTime} ms`);console.log(interactions);};go=direction=>()=>this.setState(({ count})=>({count:direction==="up" ?count+1 :count-1}));fetchData=()=>{trace("Fetch todos",performance.now(),()=>{this.setState({data:null});wrap(async()=>{try{const{ data}=awaitaxios.get("https://jsonplaceholder.typicode.com/todos/");this.setState({ data});}catch(e){console.log(e);}})();});};render(){return(<Profilerid="listPage"onRender={this.logProfile}><buttononClick={this.go("up")}>up</button><div>The count is{this.state.count}</div><buttononClick={this.go("down")}>down</button><hr/><buttononClick={()=>this.fetchData()}>refetch</button><hr/><Listdata={this.state.data}/></Profiler>);}}exportdefaultApp;

```

#### `id: string`
The `id` value of the `Profiler` tag that was measured. This value can change between renders if e.g. it is derived from `state` or `props`.
Copy link
Member

Choose a reason for hiding this comment

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

I'm a bit confused about that part. Why would theid change between renders? It sounds like the second part was meant for an additional parameter e.g. something likereason?
Was a bit confused about this part. It sounded like theid might include some metadata whyonRender was called but what this refers to is the value of theid prop e.g.<Profiler id={'tweets-' + props.userId} onRender={handleRenderCallBackWithChangingIds} />

@eps1lon
Copy link
Member

@bvaughn What are the plans for this component regardingreact-test-renderer? As it stands right nowonRender is called neither in the base renderer nor with the shallow renderer. Created a littleplayground for it (can ignore theenzyme related stuff).

I wanted to experiment with the Profiler a bit and see if I can use this to create some performance regression test that work with a performance budget. While I'm not sure if this makes sense withshallow the base renderer should probably work. Note that theshallow renderer explicitly callsrender butonRender is never called andshallow even throws when theProfiler is the root component.

The timings probably don't make much sense with the base orshallow renderer. At least for counting the render cycles it might add some value.

baseDuration: number,
startTime: number,
commitTime: number,
interactions: Array<{ name: string, timestamp: number }>,
Copy link
Member

Choose a reason for hiding this comment

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

Shape changed slightly and matches in 16.8.4 (guess this originates in thescheduler?)

Suggested change
interactions:Array<{ name: string, timestamp: number }>,
interactions:Set<{ id: number; name: string, timestamp: number }>,

Will the implementation change or is the proposal outdated?

Copy link
CollaboratorAuthor

Choose a reason for hiding this comment

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

Ah, yeah. This RFC is a bit outdated.

@bvaughn
Copy link
CollaboratorAuthor

bvaughn commentedMar 19, 2019
edited
Loading

@bvaughn What are the plans for this component regardingreact-test-renderer? As it stands right nowonRender is called neither in the base renderer nor with the shallow renderer.

The test renderer is a reconciler-based renderer, so it could support profiling and theonRender callback like any other renderer. (In fact,theProfiler tests use test renderer.) Whether it does is just a question of whethertheenableProfilerTimer feature flag is enabled, andit isn't currently for the test renderer.

WhenProfiler is released as a stable API (probably soon, I assume) we'll remove the feature flag, and it will work in the test renderer as well.

Edit for clarity I don't think it makes sense to try to support this functionality in the shallow renderer.

eps1lon reacted with thumbs up emoji

eps1lon referenced this pull request in DefinitelyTyped/DefinitelyTypedApr 30, 2019
* feat(react): Add unstable_Profiler* OnRenderCallback -> ProfilerOnRenderCallbackOnRenderCallback is to generic* Interaction -> SchedulerInteractionIt's actually part of scheduler/tracing
@bvaughn
Copy link
CollaboratorAuthor

FYI this RFC has entered the final comment period. I plan to merge it this week.

SimenB, axaxaman, and vadimaus reacted with hooray emoji

Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

@gaearongaearongaearon left review comments

+5 more reviewers

@fstoerklefstoerklefstoerkle left review comments

@jamesreggiojamesreggiojamesreggio left review comments

@alvaropinotalvaropinotalvaropinot left review comments

@eps1loneps1loneps1lon left review comments

@j-f1j-f1j-f1 left review comments

Reviewers whose approvals may not affect merge requirements

Assignees

No one assigned

Labels

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

18 participants

@bvaughn@fbartho@tizmagik@gaearon@paularmstrong@alvaropinot@miraage@jamesreggio@ljharb@jpnelson@jrnail23@lixiong-intelex@swyxio@lippyDesign@eps1lon@fstoerkle@j-f1@facebook-github-bot

[8]ページ先頭

©2009-2025 Movatter.jp