Skip to content

Distribute source maps for easier debugging in Chrome's Performance tab #20186

Closed

Description

@astoilkov

I want to propose the addition of a new file in the react-dom npm package called react-dom.production.js — a non-minified version of react-dom production build.

Edit: After some discussion(see below) it seems that distributing source maps makes more sense. Source maps will help you see the real function names and explore them. (The points below apply for source maps as well.)

Why?

There are a few ways to profile React's performance — none of them provide a low-level view of what's happening. I believe the best way to profile React is using Chrome's Performance tab using a non-minified production build. Here's why:

  • Familiar. People use the Performance tab for every other performance profiling so they are familiar with how to use it.
  • Powerful. The Performance tab is extremely powerful. Years of engineering have been put into developing it.
  • Better understanding. When using the React DevTools profiler I have a common problem – I see a component being rendered slowly but I don't know what is causing it. In order to understand I need a more low-level view. Here are some questions that can be answered only with the Chrome Performance tab:
    • What's the balance between the app's code and React execution times? Should I implement some frequently updated components using custom non-React implementation?
    • What time is spend on setting attribute values, setting innerHTML and adding and removing listeners?
    • What time is spent on disposing effects? Is there a specific dispose function that is taking more than usual?
    • What time is spent on mounting effects? Is there a specific effect mount that is taking more than usual?

Disadvantages

As with every solution, there are some drawbacks to using this approach:

  • Documentation needed. In order to make sense of what's happening you will need some knowledge of the core functions in React. A little guide with the names of the functions for mount/unmount, effects, and DOM manipulations will be useful. This of course can be done by the community(you are already linking to some community posts in React's documentation).
  • Requires more skill. This isn't for everybody. It's aimed at more experienced developers. This type of profiling is a lot more overwhelming than the current approach.
  • May not fit your principles. Maybe it's not part of your principles to introduce and promote such a complicated solution. Maybe you are more interested in searching for a more elegant and minimal solution.

Activity

  1. bvaughn commented on Nov 7, 2020

    @bvaughn
    Contributor

    I don't understand this issue. Why does a minified build prevent you from using the browser's profiling tools?

  2. astoilkov commented on Nov 7, 2020

    @astoilkov
    Author

    You can use the profiling tools but it is hard to reason about what's happening because of the minified function names. I will give some examples of when it is useful to have the real names:

    • if I see flushPassiveEffectsImpl() taking a lot of time I know I should look at some of the dispose methods of effects
    • if I see a lot of calls to setValueForProperty() then I can think of lowering the number of attributes I am changing
    • if I see a lot of time spent inside an anonymous function which parent is updateDOMProperties() then I can change/remove the dangerouslySetInnerHTML

    I can also answer the question "what time is used by React" which may let me use a custom implementation in performance-critical sections.

    I can also click on every function I don't know about and explore the code and comments there and makes sense of what is happening.

  3. changed the title [-]Support for profiling React production with Chrome's Performance tab[/-] [+]Distribute non-minified React production build for easier debugging in Chrome's Performance tab[/+] on Nov 7, 2020
  4. astoilkov commented on Nov 7, 2020

    @astoilkov
    Author

    I think I understood why you were confused. From what I wrote it seems like it isn't possible to profile the production build. I changed the title to reflect that. My proposal is for improving the experience when profiling production.

  5. bvaughn commented on Nov 7, 2020

    @bvaughn
    Contributor

    The React Profiler API, the DevTools extension profiler, and our experimental scheduling profiler are meant to give insight into the types of things you mention. Given the complexity of the internal React implementation, the profiling tools we maintain are probably going to provide better insight than manually inspecting React the way you describe. (That kind of manual inspection is often difficult even for those of us who work in React core daily.)

    I wonder if providing source maps would help address the problem you mention of occasionally needing to step through React internals?

  6. changed the title [-]Distribute non-minified React production build for easier debugging in Chrome's Performance tab[/-] [+]Distribute source-maps for easier debugging in Chrome's Performance tab[/+] on Nov 7, 2020
  7. astoilkov commented on Nov 7, 2020

    @astoilkov
    Author

    I should have thought about source maps. I think this is the ideal solution. It's way better than my proposal.

    Is there a way that the Profiler API and the DevTools extension shows the time spend on user code and React code separately? Also is there a way to see which part of the React code is taking the longest?

    I will experiment with the scheduling profiler. This is the first time I've heard about it.

  8. changed the title [-]Distribute source-maps for easier debugging in Chrome's Performance tab[/-] [+]Distribute source maps for easier debugging in Chrome's Performance tab[/+] on Nov 7, 2020
  9. bvaughn commented on Nov 7, 2020

    @bvaughn
    Contributor

    Is there a way that the Profiler API and the DevTools extension shows the time spend on user code and React code separately? Also is there a way to see which part of the React code is taking the longest?

    No. These tools show the time spent in user code. This is because (a) a lot of energy has already been put into making React as fast as we can (given constraints) and (b) it's more feasible for people to performance-tune their own components and not React anyway.

  10. astoilkov commented on Nov 7, 2020

    @astoilkov
    Author

    No. These tools show the time spent in user code. This is because (a) a lot of energy has already been put into making React as fast as we can (given constraints) and (b) it's more feasible for people to performance-tune their own components and not React anyway.

    Thanks, makes sense.

    What do you think about the source maps idea? Are you open to discussing and implementing it?

  11. bvaughn commented on Nov 7, 2020

    @bvaughn
    Contributor

    Discussing it seems fine!

  12. astoilkov commented on Nov 7, 2020

    @astoilkov
    Author

    Adding an issue I found on the topic: Question: Building react with sourcemaps.

  13. 0xdevalias commented on Jul 10, 2021

    @0xdevalias
    Contributor

    I wonder if providing source maps would help address the problem you mention of occasionally needing to step through React internals?

    This would definitely be useful for me. I actually just went looking to see if I could find sourcemaps for React (specifically we're using the minified production profiling versions of react, react-dom, etc.

    My main use case is 'occasionally digging through things while profiling', but it would also provide better context if/when errors happen deep in React's code and are reported to Bugsnag/etc. As currently the stack traces tend to be a whole lot of minified/mangled names.

    I would definitely want this to be as separate .map files rather than inlined though, as a majority of the time we wouldn't want/need the browser to be loading them.

    It looks like the places referenced in #14361 for enabling sourcemaps are:

    Curious, is this the only place that would need to be changed for this? If not, what would be the canonical way for enabling this (even if only to build my own versions)?

  14. jasonwilliams commented on Jul 15, 2021

    @jasonwilliams
    Contributor

    I got this working somewhat, I updated Rollup and all of the plugins, set sourcemaps to true and SourceMaps: true in the babel config. Then worked through the plugins. Mainly by commenting them out then trying to build and adding them back in.

    Some I had to comment out though as i don't know how to add mapping support to some of these internal plugins I think closure and strip-unused-imports can be replaced by the terser plugin. Sizes could be replaced by https://www.npmjs.com/package/rollup-plugin-sizes

    I've had to give up for now though, if anyone else was looking into it that's what i've done

  15. 10 remaining items

  16. 0xdevalias commented on Jul 10, 2022

    @0xdevalias
    Contributor

    PR added: #21946

    I feel its close, but one of the plugins renderChunk needs looking at. And i don't understand why some production builds have shouldStayReadable set. So it gets minified then re-beautified by prettier. This seems odd to me but im sure there's logic to it somewhere. I don't think sourcemaps for these builds are needed if the output is already beautified.

    @jasonwilliams Thanks for your work on that PR! It's taken me forever to get back to this, but I spent some time today going through it, leaving some rather in depth context/comments/etc, as well as researching solutions to what I believe should be the rest of the remaining issues.:

    A rather verbose review + deep dive research into the context of why certain changes were made here, as well as potential solutions for what I believe are the remaining issues that would block this PR from landing. At least in theory, I think all of the potential issues have solutions now. Would love to see this work able to land!

    There are a few minor code cleanup 'suggestions' as well, which can all be automatically applied as a single commit as follows:

    Originally posted by @0xdevalias in #21946 (review)


    Would be awesome if we were able to get this feature finished up and merged in!

  17. bvaughn commented on Jan 10, 2023

    @bvaughn
    Contributor

    Finding myself wanting this again this morning, trying to debug invariant=321.

    https://twitter.com/brian_d_vaughn/status/1612806202559459330

  18. markerikson commented on Feb 21, 2023

    @markerikson
    Contributor

    I'm gonna do the annoying "+1" thing - this is something I'd love to see added to the React packages! (and tbh it's kind of surprising it hasn't been yet.) I've spent a fair amount of time needing to debug into the guts of React, and it would be a lot easier to do that if the prod builds actually included sourcemaps. (I know that this would increase the size of the published packages on NPM, but hopefully it would be worth it!)

  19. markerikson commented on Mar 14, 2023

    @markerikson
    Contributor

    Brian asked Dan about this on Twitter:

    Dan's willing to look at a PR, but A) have to stick with Closure Compiler and not switch to Terser, B) there's concerns over "commitment" to keep them working vs hypothetical future build tooling changes.

    I'm willing to take a stab at a new PR to get sourcemaps working with Closure Compiler, and will try to take a look at that later this week.

  20. markerikson commented on Mar 17, 2023

    @markerikson
    Contributor

    Good news, folks! As of a few minutes ago, I have:

    • Found and fixed a bug with the current Rollup 2.x build config (weird tree-shaking issues in react-server-dom-webpack-server artifacts)
    • Successfully upgraded to Rollup 3.x, and generated effectively-identical build artifacts as current main with Rollup 2.x
    • Managed to generate sourcemaps for production artifacts that contain the contents of "the prod bundle right before it was minified" rather than "the original-original source files", _and appear to be 100% accurate!

    Here's a screenshot of a random function from within the react-dom.production.js bundle:

    image

    I've got a bunch of cleanup and additional verification to do, but I'm fairly positive I have this working as desired.

    Overall, I think there's 3 PRs that ought to be merged:

    1. Cleanup of the existing Rollup 2.x config, fixing that tree-shaking issue and removing a seemingly-dead "remove unused imports" plugin
    2. Upgrading to Rollup 3.x. There's an existing PR at Update rollup to v3 #26078 , and my own changes were almost identical to that.
    3. Actually applying the changes to generate sourcemaps.

    I'll see if I can file the cleanup PR early Monday, and hopefully we can get the Rollup 3.x PR in shortly after that.

    (Alternately, I could do all these in one PR. It's not that many additional changes. It's just nice to have more granular traceability to why each change was made.)

    update

    After discussing with Dan, I'm going to file the 3 separate PRs myself on Monday. Those will supersede the existing stale "generate sourcemaps" PR and the existing "Rollup 3.x" PR, and I can work on getting those pushed through ASAP.

  21. markerikson commented on Mar 20, 2023

    @markerikson
    Contributor

    Okay, I just filed #26446 , which adds the sourcemap generation to React's build config!

    That should hopefully generate some packages via CodeSandbox CI in a few minutes, and we can now test out that the sourcemaps actually get included and do something useful :)

  22. added a commit that references this issue on Nov 7, 2023
    2c8a139
  23. added a commit that references this issue on Nov 7, 2023
    c7e4e4f
  24. 0xdevalias commented on Dec 1, 2023

    @0xdevalias
    Contributor

    For those of us who were interested in sourcemap support for easier debugging/etc, just wanted to highlight 2 other issues that would improve things even more that you might like to watch/support:

  25. added a commit that references this issue on Apr 15, 2024
    b637c3b
  26. added a commit that references this issue on Apr 18, 2024
    d8d66eb
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions