React.memo performance is worse than with React.PureComponent












4














Some time ago I did refactoring of cell renderers components to achieve performance gain (I have a huge table). I did refactoring from functional stateless components to PureComponent. E.g.:



import React from 'react';
import PropTypes from 'prop-types';

class SomeCell extends React.PureComponent {
render() {
const { pizzaOrder } = this.props;
return (
<>
{pizzaOrder.name}
<br />
{pizzaOrder.price}
</>
);
}
}

SomeCell .propTypes = {
pizzaOrder: PropTypes.object,
};

export default SomeCell ;


Now I saw that React.memo was released so I updated to react@16.6.0 and react-dom@16.6.0 (from 16.5.2) and refactored from PureComponent to React.memo with an expectation that it would be even faster (no lifecycle methods called, function smaller than class in memory etc...):



import React from 'react';
import PropTypes from 'prop-types';

const SomeCell = React.memo(function({ pizzaOrder }) {
return (
<>
{pizzaOrder.name}
<br />
{pizzaOrder.price}
</>
);
});

SomeCell .propTypes = {
pizzaOrder: PropTypes.object,
};

export default SomeCell;


And to my surprise, performance went significantly down.



Do you have any idea what could be the issue with it?



Profile data in prod mode (no addons in chrome) show that there's much more scripting happening then before with PureComponent (scripting time for my case went from 0.5s to 3.8sek).



EDIT: after some investigation, it seems that it is not an issue with React.memo but with a new version of React. I've reverted cell renderers to PureComponent and left new react@16.6.0 version and the result (significantly slower performance) is still present










share|improve this question
























  • can you report it as an issue into their github?
    – skyboyer
    Nov 5 at 13:30
















4














Some time ago I did refactoring of cell renderers components to achieve performance gain (I have a huge table). I did refactoring from functional stateless components to PureComponent. E.g.:



import React from 'react';
import PropTypes from 'prop-types';

class SomeCell extends React.PureComponent {
render() {
const { pizzaOrder } = this.props;
return (
<>
{pizzaOrder.name}
<br />
{pizzaOrder.price}
</>
);
}
}

SomeCell .propTypes = {
pizzaOrder: PropTypes.object,
};

export default SomeCell ;


Now I saw that React.memo was released so I updated to react@16.6.0 and react-dom@16.6.0 (from 16.5.2) and refactored from PureComponent to React.memo with an expectation that it would be even faster (no lifecycle methods called, function smaller than class in memory etc...):



import React from 'react';
import PropTypes from 'prop-types';

const SomeCell = React.memo(function({ pizzaOrder }) {
return (
<>
{pizzaOrder.name}
<br />
{pizzaOrder.price}
</>
);
});

SomeCell .propTypes = {
pizzaOrder: PropTypes.object,
};

export default SomeCell;


And to my surprise, performance went significantly down.



Do you have any idea what could be the issue with it?



Profile data in prod mode (no addons in chrome) show that there's much more scripting happening then before with PureComponent (scripting time for my case went from 0.5s to 3.8sek).



EDIT: after some investigation, it seems that it is not an issue with React.memo but with a new version of React. I've reverted cell renderers to PureComponent and left new react@16.6.0 version and the result (significantly slower performance) is still present










share|improve this question
























  • can you report it as an issue into their github?
    – skyboyer
    Nov 5 at 13:30














4












4








4


3





Some time ago I did refactoring of cell renderers components to achieve performance gain (I have a huge table). I did refactoring from functional stateless components to PureComponent. E.g.:



import React from 'react';
import PropTypes from 'prop-types';

class SomeCell extends React.PureComponent {
render() {
const { pizzaOrder } = this.props;
return (
<>
{pizzaOrder.name}
<br />
{pizzaOrder.price}
</>
);
}
}

SomeCell .propTypes = {
pizzaOrder: PropTypes.object,
};

export default SomeCell ;


Now I saw that React.memo was released so I updated to react@16.6.0 and react-dom@16.6.0 (from 16.5.2) and refactored from PureComponent to React.memo with an expectation that it would be even faster (no lifecycle methods called, function smaller than class in memory etc...):



import React from 'react';
import PropTypes from 'prop-types';

const SomeCell = React.memo(function({ pizzaOrder }) {
return (
<>
{pizzaOrder.name}
<br />
{pizzaOrder.price}
</>
);
});

SomeCell .propTypes = {
pizzaOrder: PropTypes.object,
};

export default SomeCell;


And to my surprise, performance went significantly down.



Do you have any idea what could be the issue with it?



Profile data in prod mode (no addons in chrome) show that there's much more scripting happening then before with PureComponent (scripting time for my case went from 0.5s to 3.8sek).



EDIT: after some investigation, it seems that it is not an issue with React.memo but with a new version of React. I've reverted cell renderers to PureComponent and left new react@16.6.0 version and the result (significantly slower performance) is still present










share|improve this question















Some time ago I did refactoring of cell renderers components to achieve performance gain (I have a huge table). I did refactoring from functional stateless components to PureComponent. E.g.:



import React from 'react';
import PropTypes from 'prop-types';

class SomeCell extends React.PureComponent {
render() {
const { pizzaOrder } = this.props;
return (
<>
{pizzaOrder.name}
<br />
{pizzaOrder.price}
</>
);
}
}

SomeCell .propTypes = {
pizzaOrder: PropTypes.object,
};

export default SomeCell ;


Now I saw that React.memo was released so I updated to react@16.6.0 and react-dom@16.6.0 (from 16.5.2) and refactored from PureComponent to React.memo with an expectation that it would be even faster (no lifecycle methods called, function smaller than class in memory etc...):



import React from 'react';
import PropTypes from 'prop-types';

const SomeCell = React.memo(function({ pizzaOrder }) {
return (
<>
{pizzaOrder.name}
<br />
{pizzaOrder.price}
</>
);
});

SomeCell .propTypes = {
pizzaOrder: PropTypes.object,
};

export default SomeCell;


And to my surprise, performance went significantly down.



Do you have any idea what could be the issue with it?



Profile data in prod mode (no addons in chrome) show that there's much more scripting happening then before with PureComponent (scripting time for my case went from 0.5s to 3.8sek).



EDIT: after some investigation, it seems that it is not an issue with React.memo but with a new version of React. I've reverted cell renderers to PureComponent and left new react@16.6.0 version and the result (significantly slower performance) is still present







reactjs






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 5 at 11:57

























asked Oct 26 at 13:31









dragonfly

7,8472386169




7,8472386169












  • can you report it as an issue into their github?
    – skyboyer
    Nov 5 at 13:30


















  • can you report it as an issue into their github?
    – skyboyer
    Nov 5 at 13:30
















can you report it as an issue into their github?
– skyboyer
Nov 5 at 13:30




can you report it as an issue into their github?
– skyboyer
Nov 5 at 13:30












2 Answers
2






active

oldest

votes


















4














As suggested by @skyboyer an issue was created in React Repository.



Summary of the issue (2018-11-11):




  • The issue was not related to React itself but to an uglify-es (buggy) optimization.


  • uglify-es is inlining code (that should not be inlined).


  • uglify-es is not actively maintained anymore.

  • The proposed solution is to use terser as a replacement.


  • If you are using uglifyjs-webpack-plugin or Webpack 4.x.x (that uses uglifyjs-webpack-plugin by default), you should change the minifier option in webpack configuration like this:



    const TerserWebpackPlugin = require('terser-webpack-plugin');

    module.exports = {
    //...
    optimization: {
    minimizer: [
    new TerserWebpackPlugin({ /* your config */ })
    ]
    }
    };







share|improve this answer





























    3














    TL;DR:




    upgrade webpack to version 4.26




    as they switched to terser as the default minimizer.



    Background:





    • uglifyjs-webpack-plugin < v1.0 used the minifier uglify-js

    • however uglify-js does not support ES6, which resulted in a fork called uglify-es that was developed in the uglify-js repository, but under the harmony branch


    • uglifyjs-webpack-plugin v1.x switched to uglify-es for ES6 support

    • however uglify-es stopped being maintained: mishoo/UglifyJS2#3156 (comment)

    • which led to a fork called terser that has incorporated all of the unmerged PRs and will be where all new development occurs: https://github.com/fabiosantoscode/terser


    • terser-webpack-plugin was created, which is the terser equivalent of uglifyjs-webpack-plugin: https://github.com/webpack-contrib/terser-webpack-plugin


    • uglifyjs-webpack-plugin v2.x will be switching back to uglify-js, so any project that needs to support ES6 now needs to switch to terser-webpack-plugin.


    Reference: webpack/commit






    share|improve this answer





















      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53009908%2freact-memo-performance-is-worse-than-with-react-purecomponent%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      2 Answers
      2






      active

      oldest

      votes








      2 Answers
      2






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      4














      As suggested by @skyboyer an issue was created in React Repository.



      Summary of the issue (2018-11-11):




      • The issue was not related to React itself but to an uglify-es (buggy) optimization.


      • uglify-es is inlining code (that should not be inlined).


      • uglify-es is not actively maintained anymore.

      • The proposed solution is to use terser as a replacement.


      • If you are using uglifyjs-webpack-plugin or Webpack 4.x.x (that uses uglifyjs-webpack-plugin by default), you should change the minifier option in webpack configuration like this:



        const TerserWebpackPlugin = require('terser-webpack-plugin');

        module.exports = {
        //...
        optimization: {
        minimizer: [
        new TerserWebpackPlugin({ /* your config */ })
        ]
        }
        };







      share|improve this answer


























        4














        As suggested by @skyboyer an issue was created in React Repository.



        Summary of the issue (2018-11-11):




        • The issue was not related to React itself but to an uglify-es (buggy) optimization.


        • uglify-es is inlining code (that should not be inlined).


        • uglify-es is not actively maintained anymore.

        • The proposed solution is to use terser as a replacement.


        • If you are using uglifyjs-webpack-plugin or Webpack 4.x.x (that uses uglifyjs-webpack-plugin by default), you should change the minifier option in webpack configuration like this:



          const TerserWebpackPlugin = require('terser-webpack-plugin');

          module.exports = {
          //...
          optimization: {
          minimizer: [
          new TerserWebpackPlugin({ /* your config */ })
          ]
          }
          };







        share|improve this answer
























          4












          4








          4






          As suggested by @skyboyer an issue was created in React Repository.



          Summary of the issue (2018-11-11):




          • The issue was not related to React itself but to an uglify-es (buggy) optimization.


          • uglify-es is inlining code (that should not be inlined).


          • uglify-es is not actively maintained anymore.

          • The proposed solution is to use terser as a replacement.


          • If you are using uglifyjs-webpack-plugin or Webpack 4.x.x (that uses uglifyjs-webpack-plugin by default), you should change the minifier option in webpack configuration like this:



            const TerserWebpackPlugin = require('terser-webpack-plugin');

            module.exports = {
            //...
            optimization: {
            minimizer: [
            new TerserWebpackPlugin({ /* your config */ })
            ]
            }
            };







          share|improve this answer












          As suggested by @skyboyer an issue was created in React Repository.



          Summary of the issue (2018-11-11):




          • The issue was not related to React itself but to an uglify-es (buggy) optimization.


          • uglify-es is inlining code (that should not be inlined).


          • uglify-es is not actively maintained anymore.

          • The proposed solution is to use terser as a replacement.


          • If you are using uglifyjs-webpack-plugin or Webpack 4.x.x (that uses uglifyjs-webpack-plugin by default), you should change the minifier option in webpack configuration like this:



            const TerserWebpackPlugin = require('terser-webpack-plugin');

            module.exports = {
            //...
            optimization: {
            minimizer: [
            new TerserWebpackPlugin({ /* your config */ })
            ]
            }
            };








          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 12 at 1:24









          agarwaen

          1,4551533




          1,4551533

























              3














              TL;DR:




              upgrade webpack to version 4.26




              as they switched to terser as the default minimizer.



              Background:





              • uglifyjs-webpack-plugin < v1.0 used the minifier uglify-js

              • however uglify-js does not support ES6, which resulted in a fork called uglify-es that was developed in the uglify-js repository, but under the harmony branch


              • uglifyjs-webpack-plugin v1.x switched to uglify-es for ES6 support

              • however uglify-es stopped being maintained: mishoo/UglifyJS2#3156 (comment)

              • which led to a fork called terser that has incorporated all of the unmerged PRs and will be where all new development occurs: https://github.com/fabiosantoscode/terser


              • terser-webpack-plugin was created, which is the terser equivalent of uglifyjs-webpack-plugin: https://github.com/webpack-contrib/terser-webpack-plugin


              • uglifyjs-webpack-plugin v2.x will be switching back to uglify-js, so any project that needs to support ES6 now needs to switch to terser-webpack-plugin.


              Reference: webpack/commit






              share|improve this answer


























                3














                TL;DR:




                upgrade webpack to version 4.26




                as they switched to terser as the default minimizer.



                Background:





                • uglifyjs-webpack-plugin < v1.0 used the minifier uglify-js

                • however uglify-js does not support ES6, which resulted in a fork called uglify-es that was developed in the uglify-js repository, but under the harmony branch


                • uglifyjs-webpack-plugin v1.x switched to uglify-es for ES6 support

                • however uglify-es stopped being maintained: mishoo/UglifyJS2#3156 (comment)

                • which led to a fork called terser that has incorporated all of the unmerged PRs and will be where all new development occurs: https://github.com/fabiosantoscode/terser


                • terser-webpack-plugin was created, which is the terser equivalent of uglifyjs-webpack-plugin: https://github.com/webpack-contrib/terser-webpack-plugin


                • uglifyjs-webpack-plugin v2.x will be switching back to uglify-js, so any project that needs to support ES6 now needs to switch to terser-webpack-plugin.


                Reference: webpack/commit






                share|improve this answer
























                  3












                  3








                  3






                  TL;DR:




                  upgrade webpack to version 4.26




                  as they switched to terser as the default minimizer.



                  Background:





                  • uglifyjs-webpack-plugin < v1.0 used the minifier uglify-js

                  • however uglify-js does not support ES6, which resulted in a fork called uglify-es that was developed in the uglify-js repository, but under the harmony branch


                  • uglifyjs-webpack-plugin v1.x switched to uglify-es for ES6 support

                  • however uglify-es stopped being maintained: mishoo/UglifyJS2#3156 (comment)

                  • which led to a fork called terser that has incorporated all of the unmerged PRs and will be where all new development occurs: https://github.com/fabiosantoscode/terser


                  • terser-webpack-plugin was created, which is the terser equivalent of uglifyjs-webpack-plugin: https://github.com/webpack-contrib/terser-webpack-plugin


                  • uglifyjs-webpack-plugin v2.x will be switching back to uglify-js, so any project that needs to support ES6 now needs to switch to terser-webpack-plugin.


                  Reference: webpack/commit






                  share|improve this answer












                  TL;DR:




                  upgrade webpack to version 4.26




                  as they switched to terser as the default minimizer.



                  Background:





                  • uglifyjs-webpack-plugin < v1.0 used the minifier uglify-js

                  • however uglify-js does not support ES6, which resulted in a fork called uglify-es that was developed in the uglify-js repository, but under the harmony branch


                  • uglifyjs-webpack-plugin v1.x switched to uglify-es for ES6 support

                  • however uglify-es stopped being maintained: mishoo/UglifyJS2#3156 (comment)

                  • which led to a fork called terser that has incorporated all of the unmerged PRs and will be where all new development occurs: https://github.com/fabiosantoscode/terser


                  • terser-webpack-plugin was created, which is the terser equivalent of uglifyjs-webpack-plugin: https://github.com/webpack-contrib/terser-webpack-plugin


                  • uglifyjs-webpack-plugin v2.x will be switching back to uglify-js, so any project that needs to support ES6 now needs to switch to terser-webpack-plugin.


                  Reference: webpack/commit







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 25 at 12:02









                  Idan Dagan

                  1,48211023




                  1,48211023






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.





                      Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                      Please pay close attention to the following guidance:


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53009908%2freact-memo-performance-is-worse-than-with-react-purecomponent%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Florida Star v. B. J. F.

                      Danny Elfman

                      Retrieve a Users Dashboard in Tumblr with R and TumblR. Oauth Issues