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

Slim down the React build #119

Open
ustun opened this issue Mar 5, 2019 · 5 comments
Open

Slim down the React build #119

ustun opened this issue Mar 5, 2019 · 5 comments
Assignees

Comments

@ustun
Copy link

ustun commented Mar 5, 2019

I created a brand new React-TypeScript addin using the yo office generator. The sample project, without any changes results in almost 3 MB of JS output. This seems like an important problem since I assume a lot of people will be starting with this generator, and we might see big addins that might slow down Office apps.

Here is what npm run build displays:

                                    Asset       Size  Chunks                    Chunk Names
              app.84c970d255d072636045.js   1.19 MiB       0  [emitted]  [big]  app
          app.84c970d255d072636045.js.map   3.87 MiB       0  [emitted]         app
                       assets/icon-16.png   1.56 KiB          [emitted]         
                       assets/icon-32.png   2.33 KiB          [emitted]         
                       assets/icon-80.png   4.72 KiB          [emitted]         
                   assets/logo-filled.png   11.6 KiB          [emitted]         
    function-file.84c970d255d072636045.js   1.12 KiB       1  [emitted]         function-file
function-file.84c970d255d072636045.js.map   4.92 KiB       1  [emitted]         function-file
         function-file/function-file.html  830 bytes          [emitted]         
                               index.html  841 bytes          [emitted]         
           vendor.84c970d255d072636045.js   1.06 MiB       2  [emitted]  [big]  vendor
       vendor.84c970d255d072636045.js.map   3.87 MiB       2  [emitted]         vendor

Summary of Problems:

  • The current React template loads office-fabric and ui-fabric twice, both in app.js and in vendor.js. It is ignoring that it has been loaded into vendor.js and it is being included in app.js as well.
  • No tree shaking for office-fabric, even if you use a button, it seems to load the whole library.

I enabled the webpack-bundle-analyzer https://www.npmjs.com/package/webpack-bundle-analyzer and here is the report it generated on the production build:

screen shot 2019-03-05 at 12 17 50

Some suggestions for improvement:

  • splitChunks's chunks property is "async", changing this to "all" helps a little.
  • entry point is an array that includes react-hot-loader, having an array seems to disable some of webpack's optimizations. See improve production bundle size microsoft/fluentui#7581 (comment)
  • Importing from the internals of the library helps. If I change
    import { Button, ButtonType } from "office-ui-fabric-react";
    to
    import { Button, ButtonType } from "office-ui-fabric-react/lib/Button";
    it seems to just import the Button. I think webpack should be handling this, but there is something lost in translation, so this optimization is not done automatically for some reason.
  • Also see improve production bundle size microsoft/fluentui#7581 which discusses similar issues.
@TCourtneyOwen
Copy link
Contributor

@ustun Thanks for opening this issue. We realize this is a problem with the React template and will open a work item on our end to address this issue in the near future

Thanks,

Courtney

@sanzoghenzo
Copy link

sanzoghenzo commented Mar 25, 2020

Having the same issue, I partially solved by removing the "vendors" entry in webpack.config.js as stated in the webpack 4 official documentation.
That alone will pack everything in the app entry, because of the default settings of the new SplitChunksPlugin.

I tried adding the following config:

optimization: {
  splitChunks: { chunks: "all" },
  runtimeChunk: true,
},

but it broke my app.

For now I'm happy enough using a single chunk with everything in it.

@unhammer
Copy link

Removing the whole vendor: […] part from webpack.config.js made the build about 4x smaller for me :)

After that, selective imports of Button ("office-ui-fabric-react/lib/Button") had no effect on size.

@daniesy
Copy link

daniesy commented Jun 30, 2020

Selective imports worked and shrank everything way down for me. Strangely enough, this is how Microsoft recommends using the fabric ui library in some guides. You just need to be careful to do it everywhere in your project. Also, you don't need to remove the whole vendor part from webpack.config.js, deleting theoffice-ui-fabric-react should be enough. I had to remove the fabric.min.css from the taskpane code as well, freeing up 800kb.

This way I got from:

taskpane.js (2.32 MiB)
vendor.js (1.18 MiB)

down to:

taskpane.js (399 KiB)
vendor.js (252 KiB)

@millerds millerds self-assigned this May 24, 2022
@millerds
Copy link
Contributor

I've recently done some improvement here, but I'll check if there is more to be done.

@millerds millerds transferred this issue from OfficeDev/generator-office Apr 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants