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

Webpack incremental builds are slow #616

Open
quicksnap opened this issue Nov 25, 2015 · 112 comments
Open

Webpack incremental builds are slow #616

quicksnap opened this issue Nov 25, 2015 · 112 comments

Comments

@quicksnap
Copy link
Collaborator

On my machine, incremental builds in dev mode take anywhere from 1.5s - 5s.

I'm going to spend some time toying with webpack to see what's up, but I'd appreciate anyone else's ideas on what's going wrong.

@quicksnap
Copy link
Collaborator Author

I'm able to drop the rebuild time significantly without bootstrap/font-awesome loaders in the main entry. Going to look into splitting it into a separate chunk.

@trueter
Copy link
Contributor

trueter commented Nov 26, 2015

Sounds great!

@wwwfreedom
Copy link

I'm getting slow build time as well. Looking forward to your split set up.

@luankefei
Copy link

I am the same. it happened looks like webpack-hot-middleware didn't work.

@bdefore
Copy link
Collaborator

bdefore commented Nov 26, 2015

@quicksnap if you set your devtool to inline-eval-cheap-source-map in dev.config.js i've noticed around 75% speed improvement on rebuilds, 10% improvement on initial builds. there's some discussion around why source mapping is expensive in recent versions, and it looks like it might be due to css-loader's implementation of css modules. you may also want to upgrade node-sass to 3.4.x. looks like the example project still has 3.3.3 which @Phoenixmatrix identified as having poor performance: webpack-contrib/sass-loader#176

@cjhveal
Copy link

cjhveal commented Nov 26, 2015

If I'm not mistaken, PR #614 upgraded node-sass to ^3.4.2.

@erikras
Copy link
Owner

erikras commented Nov 27, 2015

Dupes #594

@quicksnap
Copy link
Collaborator Author

Weird.. I thought I commented a reply to @bdefore:

Modifying or even removing the devtool doesn't do much for me. In my case, it's nearly all time due to the bootstrap-loader plugin. When I remove that, my rebuild time drops from ~4000ms to <500ms.

It would be nice to understand exactly what is going on. I tried digging into the plugin itself, but any modifications I made would not yield positive results, other than causing it not to generate the SASS file which @imports all the bootstrap stuff.

I have a feeling it's not properly caching due to its usage of a pitch loader. I'm not sure though, and it's tough to get help or even form an educated question.

Personally, I may just remove bootstrap loader and use a static build of bootstrap. I'm not sure the best route for this project.

Would love it if someone could see why bootstrap-loader isn't caching on rebuilds. Or anything to drop rebuild times <1000ms

@quicksnap
Copy link
Collaborator Author

Perhaps it's simply that bootstrap generates a ton of CSS, and css-loader chokes on that.

I will try bypassing css-loader for bootstrap and see what happens.

@Phoenixmatrix
Copy link

I don't know much on bootstrap-loader, but saw this since i got tagged on it. Its possible what's below is irrelevant, but I'll pitch it in anyway. Though it sounds like its just the loader not caching, as as mentioned.

I dont know what boostrap loader does, but do keep in mind that SASS doesn't get incrementally compiled the same way JS does. If you require(...) SASS, it creates a css "entry point" so to speak, but if inside that SASS, you @import other stuff, that's all part of the same "sass build". Sass builds are not incremental, and all SASS within a single "entry point" will get recompiled every time.

node-sass <3.4 is slow, and css-loader after 0.14.5 is BRUTALLY slow (to the point of being unusable). Since all of your CSS may get recompiled if its all in the same CSS entry point, you can quickly end up in CSS builds that take longer than rebuilding your entire JS from scratch, even though you only added 1 character to 1 CSS file.

Note that splitting your CSS by requiring it from JS isn't always a good answer in SASS because of the lack of @import (reference) like LESS does...you may end up duplicating a lot of stuff if you're not careful.

tl;dr: CSS builds using the @import mechanic are not incremental and cause a full rebuild of that part. You probably want a static bootstrap build, and @import only variables and mixins as need be (but nothing else!)

@quicksnap
Copy link
Collaborator Author

@Phoenixmatrix thanks. The problem with this setup is that whenever we change any of our JS files, it triggers an entire rebuild, including the CSS. I could not figure a way to tell webpack not to rebuild bootstrap-sass every time. It is doing so here: https://github.com/erikras/react-redux-universal-hot-example/blob/master/webpack/dev.config.js#L54

I tried splitting out into a different chunk, but no luck. My webpack chops are mediocre.

I'm tooling around with bootstrap-sass-loader code now, but I still am not entirely sure where the slowness is being generated.

@Phoenixmatrix
Copy link

Yeah, i realized that afterward rereading your comment. Whoops! For sure upgrading to node 3.4 should speed that up since compiling bootstrap shouldn't take very long at all, but obviously that only fixes symptoms (did you know node-sass is like 2-3 times faster on Linux than MacOSX? fun stuff).

Will take a look at the bootstrap sass loader when I get the chance.

@quicksnap
Copy link
Collaborator Author

Thanks for helping out! Appreciate it.

Be sure to change the devtool to something fast like inline-eval-cheap-source-map. I forgot to do that and it was screwing up my benchmarks.

@quicksnap
Copy link
Collaborator Author

Ok! I just changed devtool to inline-eval-cheap-source-map, and then edited bootstrap-sass-loader to this: quicksnap/bootstrap-sass-loader@6e60e0f (switch out css-loader for raw-loader)

This significantly speeds things up for me.

@quicksnap
Copy link
Collaborator Author

I think it still would be an even better improvement if we could get webpack to avoid rebuilding bootstrap unless the bootstrap config file changes.

@Phoenixmatrix
Copy link

Yeah, so obviously that part is still broken. But also, yet another reason
css-loader needs to be fixed. Its so completely broken performance wise
right now, as per webpack-contrib/css-loader#124

In our codebase its unusable (css build takes minutes, so we have to use
raw-loader)

@quicksnap
Copy link
Collaborator Author

I hope it is improved by the time our css grows. I really like CSS Modules...

@mmahalwy
Copy link

mmahalwy commented Dec 1, 2015

@quicksnap seems like you're suggesting to avoid bootstrap-sass-loader? That seems to be the bottleneck?

@bdefore
Copy link
Collaborator

bdefore commented Dec 1, 2015

i had a chat with the shakacode folks this morning and discovered that bootstrap-sass-loader is being rewritten and will soon be deprecated. the rewritten version is here, though it hasn't been touched in a couple weeks: https://github.com/shakacode/bootstrap-loader/tree/alex/bootstrap-4

@quicksnap
Copy link
Collaborator Author

@mmahalwy I'm not recommending avoiding it--I'll try to issue a PR to bootstrap-sass-loader soon. The change is minor. I don't see any problems using raw-loader over css-loader in bootstrap-sass-loader.

@Phoenixmatrix
Copy link

Raw loader will not rewrite image and font URLs if you hash them. I don't
know if it affects bootstrap in any way.

On Tue, Dec 1, 2015, 1:24 PM Dan Schuman [email protected] wrote:

@mmahalwy https://github.com/mmahalwy I'm not recommending avoiding
it--I'll try to issue a PR to bootstrap-sass-loader soon. The change is
minor. I don't see any problems using raw-loader over css-loader in
bootstrap-sass-loader.


Reply to this email directly or view it on GitHub
#616 (comment)
.

-Francois Ward

@quicksnap
Copy link
Collaborator Author

@Phoenixmatrix good point. I'll check on that, but I have a feeling it could cause issues now.

@quicksnap
Copy link
Collaborator Author

I'll also look into passing params to css-loader to disable some things, or to downgrade css-loader in that repository.

@quicksnap
Copy link
Collaborator Author

Or, having css-loader be a peer dependency.

@trueter
Copy link
Contributor

trueter commented Dec 2, 2015

@quicksnap: I tried splitting out into a different chunk, but no luck. My webpack chops are mediocre.

What was the reason you gave up on this route? Having bootstrap outside the main chunk might circumvent the recompile issue.

@quicksnap
Copy link
Collaborator Author

@trueter yes--I couldn't figure how to prevent bootstra-sass-loader from being triggered every rebuild. I did get it into a separate chunk successfully, but it would always rebuild all chunks AFAIK (it would say 'emitted' next to the vendor chunk I created).

@mmahalwy
Copy link

mmahalwy commented Dec 4, 2015

@quicksnap any luck on this so far?

@quicksnap
Copy link
Collaborator Author

@mmahalwy I haven't messed with adjusting bootstrap-sass-loader's properties yet. I'm also not sure if bootstrap-sass has any image URLs in it, so it may actually be good with raw-loader, which would be hella faster.

I'm working on stuff right now that doesn't involve dev mode, but next time I get hit with a 4sec rebuild I'll probably dig in.

@sars
Copy link
Contributor

sars commented Dec 12, 2015

@quicksnap what's your build time now?
I've just launched this example and it takes 3.5-5 sec for me for each build...
it really slows down development..

Did you figure out how to speed it up?

@trueter
Copy link
Contributor

trueter commented Dec 15, 2015

@quicksnap could you create a pr with your code split work in progress? stumbled across this: http://tech.trivago.com/2015/12/15/parallel-webpack/

@catamphetamine
Copy link
Contributor

@delvarworld Well, I don't know what's going on there but I don't think you can cache assets with webpack-isomorphic-tools (maybe with universal-webpack). If your assets aren't in webpack-stats.json then they won't be found. webpack-stats.json are generated by Webpack.

@amireh
Copy link

amireh commented Jun 27, 2016

By the way, posting here since it's relevant to this discussion: there's a pending PR for DLL support (#1201) but it bases off the happypack PR #1090. With some effort, you could define an asset DLL (some README exists for defining more DLLs). There might be issues with webpack-isomorphic-tools though.

Perhaps you could try those patches out?

@AndrewRayCode
Copy link
Contributor

@halt-hammerzeit Thanks for the help so far, I've discovered when I run my dll initial build the webpack-assets.json gets populated correctly, or at least it has all the image and scss paths in there. But when I run the default npm run dev it overwrites the contents of that file with:

{
  "javascript": {
    "main": "http://localhost:3001/dist/main-826b5781622f36dec637.js"
  },
  "styles": {},
  "assets": {
    "./~/font-awesome/fonts/fontawesome-webfont.eot": "http://localhost:3001/dist/404a525502f8e5ba7e93b9f02d9e83a9.eot"
  }
}

This is my only change to my wepback/dev.config.js file, other than removing CommonChunksPlugin

+    new webpack.DllReferencePlugin({
+      context: process.cwd(),
+      manifest: require(path.join(assetsPath, 'main-manifest.json'))
+    }),
+    new webpack.DllReferencePlugin({
+      context: process.cwd(),
+      manifest: require(path.join(assetsPath, 'vendor-manifest.json'))
+    }),
+    new webpack.DllReferencePlugin({
+      context: process.cwd(),
+      manifest: require(path.join(assetsPath, 'assets-manifest.json'))
+    }),

For my dev.config.js (not the DLL one), my entry point is simply:

  entry: {
    main: [
      'webpack-hot-middleware/client?path=http://' + host + ':' + port + '/__webpack_hmr',
      'font-awesome-webpack!./src/theme/font-awesome.config.js',
      './src/client.js'
    ],
  },

@catamphetamine
Copy link
Contributor

@delvarworld

Thanks for the help so far, I've discovered when I run my dll initial build the webpack-assets.json gets populated correctly, or at least it has all the image and scss paths in there. But when I run the default npm run dev it overwrites the contents of that file with.

Oh, maybe that's the issue - it overwrites the file.
You can try to disable webpack-isomorphic-tools plugin for the second pass so that it doesn't overwrite the correst assets file with the new empty one.

@AndrewRayCode
Copy link
Contributor

AndrewRayCode commented Jun 27, 2016

Ok cool removing webpack-isomorphic-tools from the main webpack config file preserves the manifest. Something else that's confusing is that now all of my assets can only be served from :3000 instead of :3001. I see this line in a linked config, where 1 is subtracted:

publicPath   : 'http://' + host + ':' + ( port - 1 ) + '/dist/'

But I'm not sure why this is needed? When my code starts it logs:

[0] ==> 🚧  Webpack development server listening on port 3001

But all files at :3001 error (they didn't error before the DllPlugin), and those paths only exist at :3000 now. Do you know why this is happening, and if it's an error or expected behavior?

@catamphetamine
Copy link
Contributor

The files should be available through webpack-dev-server (3001 in your case). If they aren't then it may seem that either their filenames are from another build and therefore are different or that the files aren't included in the (second?) build which could also be true since they are absent from the assets.

@AndrewRayCode
Copy link
Contributor

@trueter did you run into this issue and do you have any insight as to why you did port - 1 in your config?

@AndrewRayCode
Copy link
Contributor

AndrewRayCode commented Jun 28, 2016

Ok, finally got somewhere with the DllPlugin. I'm going to document everything I know here, for now, because the information on this is scattered, hard to find and sometimes convoluted. There are still many unknowns in this process, and I will update this reply if any of the unknowns are clarified.

Warning: It's easy to do this incorrectly. You can actually double your build size by accidentally bundling your dependencies into the Dll bundle and your main bundle. Several people in this thread have said the DllPlugin gave them no speed up, but I wonder if it was just a configuration issue.

Warning: These steps are currently specific to this project, and more specifically to webpack-dev-middleware. However the DllPlugin can be used in any Webpack project.

Warning I haven't set up the final script tag to work in a production build (yet), but it should be straightforward.

TL;DR dll.config.js and dev.config.js and hard code <script src="http://localhost:3001/dist/app.js" charSet="UTF-8"/> into Html.js but you might want to read this anyway!

Reducing My Hot Reload Time From 15s to 4s With The DllPlugin

I still have more work to do on optimizing (next will try HappyPack), but this is a serious improvement already.

My Specific Problem

I have many large asset files that are being built into my bundle. I'm building a 3d game using React and the model files are in JSON, so I have many MB of 3d model data to load. Even though they're going through the file loader, they still get built into the main bundle. I'm also including large Javascript libraries, like Three.js.

Webpack Is Slow

Out of the box, Webpack isn't efficient. In fact, it's surprising it works the way it does. Webpack treats everything, both your source and your dependencies, as one big bundle. Even in development mode. What this means in practice is that if you change any source file, ALL Javascript files, including dependencies, are re-processed and re-bundled. You can see why this would be slow. I believe this happens even if you use the CommonChunks plugin. If you change your source file, even with CommonChunks, the common chunk will get re-written (I could be wrong but that's what the last section of this post suggests).

What Is The DllPlugin?

Really, if you think about it, we don't want Webpack to touch our third party dependencies more than once. That's where the oddly named DllPlugin comes in. I don't know why it reuses the Windows development "Dynamically Linked Library" terminology, but that's what it stands for. The basic workflow is this:

  1. Create a separate, one time build step that uses the DllPlugin
  2. Run this one-time build step before your dev server. It creates both a bundle file containing your third party code, and a "manifest" file, which maps require paths to built Webpack ids, so your app code (via Webpack) knows how to find them at runtime.
  3. Modify your webpack dev config to use the DllReferencePlugin to point to the manifest file(s) built in step 2.

Don't overlook the importance of caching this manifest file. Without the DllPlugin it's re-created every time for every code change, as in Webpack walks all your dependencies to build it. Caching it for third party node modules seems like a good idea to me!

Setting up the DllPlugin

You have two options here. You can either create an entirely separate Webpack config file for the Dll build, or you can modify your existing dev.config.js file to build the Dll files if you set an environment variable. The benefit of an environment variable switch is less code duplication, the downside is it's harder to read and makes the config file more confusing. The downside of a separate file is you'll probably duplicate some config options, violating the DRY principle. I don't think either option is ideal, so go with personal preference. For this tutorial, I'm going to create a separate dll.config.js file.

Creating The Dll Configuration File

This will be a modified copy of your dev.config.js file. We'll go over each thing you need to change.

I've put the my completed dll.config.js file online for you to reference.

Every step below is done in a copy of webpack/dev.config.js that I arbitrarily name webpack/dll.config.js

1) Add an entry for your main app, but name it something different. Also it must be an array, not a single string.

entry: {
  app_assets: [ './src/client.js' ],

According to this comment, if you don't include your main entry file, the main webpack-assets.json manifest file won't include your runtime static assets like CSS, JS, etc.

2) Add an array of the third party vendor code to go into the cached manifest and bundle:

entry: {
  app_assets: [ './src/client.js' ],
  vendor: [
    'react',
    'react-dom',
    ...
  ]

How did I come up with this list? Based on an earlier comment, I modified webpack-dev-server.js to set quiet: false and noInfo: false, started the dev server, then manually copied anything starting with ./~/ into the vendor: [] array. Well, most things. I excluded Webpack-looking things like the css-loader which appears in that list.

One gotcha here is if you try to include 'babel-runtime' (which is a huge dependency) in the array it will fail, complaining it can't find it. I don't know why, but change it to 'babel-runtime/core-js'.

By the way, when this is all over, you can set the server flags again (quiet: false and noInfo: false,) and see which files are now coming from your cached manifest. They will look like:

delegated ./node_modules/redux/lib/index.js from dll-reference vendor 42 bytes {0} [not cacheable]

3) Set your output section to exactly:

  output: {
    path: assetsPath,
    filename: '[name].dll.js',
    library: '[name]',
    publicPath: 'http://' + host + ':' + ( port - 1 ) + '/dist/'
  },

Through trial and error I found that library: '[name]', is required. If you want you can change the .dll.js to something, like .bundle.js, but keep [name].

4) Include the DllPlugin

    new webpack.DllPlugin({
      name: '[name]',
      path: path.join( assetsPath, '[name]-manifest.json' ),
    }),

You may have noticed that earlier comments on this thread include things like context: undefined and other config keys. You don't need them. Again you can change the -manifest.json string, but remember what you change it to because we need it.

5) Verify your plugins

Make sure you include webpackIsomorphicToolsPlugin.development(), in the plugins: [] list for your dll.config.js file.

Modifying Your Main dev.config.js file

My final dev.config.js file is online for you to compare against.

1) Remove everything from your entry config except your main entry point

  entry: {
    main: [
      'webpack-hot-middleware/client?path=http://' + host + ':' + port + '/__webpack_hmr',
      'font-awesome-webpack!./src/theme/font-awesome.config.js',
      './src/client.js'
    ],
  },

Standard stuff here.

2) Modify your output to only build one file with an exact name

  output: {
    path: assetsPath,
    filename: 'app.js',
    publicPath: 'http://' + host + ':' + port + '/dist/'
  },

We'll come back to this later, see Unknown 2 at the end of this post for why we don't use the good old [name]-[hash] style.

3) Add DllReferencePlugin(s) to your plugins list:

  plugins: [
    new webpack.DllReferencePlugin({ 
      context: path.join( __dirname, '../' ),
      manifest: require(path.join(assetsPath, 'vendor-manifest.json')),
    }),
    ....

Add one DllReferencePlugin call for each entry you specify in dll.config.js. If you only have one vendor entry (most common case) then you only need one plugin here. Keep in mind it must match the string pattern you specified in dll.config.js (in our case [name]-manifest.json).

Do they need to go at the beginning of the plugins list? I don't know. A previous comment used unshift to put the DllReferencePlugin at the beginning of the array. I'm not deviating.

4) Remove the webpackIsomorphicToolsPlugin and CommonsChunkPlugin

Do not include webpackIsomorphicToolsPlugin nor CommonsChunkPlugin in your plugins: [] list for webpack/dev.config.js. CommonChunks can't co-exist with DllPlugin. They are competing solutions, and one clobbers the other. For why we remove webpackIsomorphicToolsPlugin, see Unknown 2

Add your new bundles to Html.js

In this project's Html.js file, include your vendor script tag(s):

<script src={assets.javascript.vendor} charSet="UTF-8"/>

Now include your hard coded app.js file, which we created in the above dev.config.js file:

<script src="http://localhost:3001/dist/app.js" charSet="UTF-8"/>

Run the manifest step and then run your project!

Here's the command I use to create the cached manifest/bundle files. You only have to run this command once, and then only again if your dependencies change:

webpack --colors --progress --config webpack/dll.config.js

Then start your server like normal:

npm run dev

If everything went well, you should have faster hot reloading!

Unknowns

Unknown 1:

According to @sokra:

If you process the file with the file-loader, they should not be included in the bundle file, but emitted as separate files

However, this boilerplate project uses webpack-isomorphic-tools and webpack-dev-middleware instead of the regular dev server, and according to the middleware docs:

No files are written to disk, it handle the files in memory

Does using webpack-dev-middleware mean that large files are always re-created in memory on every hot reload? Would this be solved by using the regular dev server and just putting files on disk that aren't touched again on hot reload? I have no idea, but I made a ticket to ask.

Unknown 2:

In the above code we removed the isomorphic tools plugin from the main dev config, and hard coded the asset path. So here's the issue. If I include webpackIsomorphicToolsPlugin in my dev.config.js file, it overwrites the contents of webpack-assets.json, which was previously created by the Dll step. This means that all the cached manifest data is clobbered. I have no idea if this is supposed to work this way, and if you're not supposed to use it in the main dev server, but...

...The other problem here is that without webpackIsomorphicToolsPlugin running on your source code, assets.javascript.main won't exist, because it's not added to the manifest. I believe webpackIsomorphicToolsPlugin is reponsible for the addition. That's why I have to hard code the path. Also this means if you want to load it from the same port as the other assets (which are 3000) you'd have to manually expose that file by adding a server route.

That's it!

This is a first draft, and hopefully it gets some good input and feedback and is refined. I don't know if this is the solution, or even an ideal solution. I've just been hacking at this frustrating problem for 2 days straight and had to jump between many sources. The Webpack docs are no help, as expected. Hopefully this helps someone!

Further reading: Webpack Plugins we been keepin on the DLL and Optimizing Webpack Build Times

(Spam) if this helped you consider following me on Twitter

@catamphetamine
Copy link
Contributor

Good post

Does using webpack-dev-middleware mean that large files are always re-created in memory on every hot reload?

If your file is processed by webpack dev server (in any way) then it resides in RAM and is recompiled only on changes to it. I would suppose the DDLRefPlugin is intelligent enough to exclude files from the DLL from webpack dev server's list of files.

I have no idea if this is supposed to work this way

It is supposed to always overwrite webpack-assets.json on a subsequent run.

and if you're not supposed to use it in the main dev server, but...

You do it in the main dev server if you're not gonna put your assets into the DLL. Otherwise, I guess, you do it in the DLL compilation run (for whatever reasons you have).

without webpackIsomorphicToolsPlugin running on your source code, assets.javascript.main won't exist

Yes, assets.javascript.main is taken from webpack-assets.json, so if it's wrong or non-existent there then it will be the same when you run the app.

(you might also consider trying universal-webpack later)

@amireh
Copy link

amireh commented Jun 28, 2016

The solution @delvarworld outlined in great detail is close to the one proposed in PR (#1201), perhaps these should converge? The only differences as far as I can tell is that it doesn't disable CommonsChunk or isomorphic-tools (although it probably should) and it tracks babel-runtime modules in the vendor DLL.

Edit: sound less obnoxious - was just trying to help. 😁 Have a great week everyone!

@Jack-Barry
Copy link

Jack-Barry commented Aug 4, 2016

It's not all that elegant but what I've done to make hot updates snappy is to run a separate, concurrent Webpack process to bundle my Bootstrap, with a configuration that doesn't have hot updates enabled. In simple terms, the basic syntax is:

module.exports = [
    { config for regular bundle with hot updates enabled, css loader ignores bootstrap },
    { config for Bootstrap using raw loader without hot updates }
];

This way, it gets passed through the loaders on initial build, but isn't touched during incremental builds. It's also running concurrently on the initial build with my regular bundle which shaves a few seconds off at that point. Still pretty long build time initially, but it seems to help for incremental builds which are more aggravating when slow. I'd still like to speed up that initial build but that seems a lot more doable using something like this. I'm thinking of setting up a webpack-vendor.config.js so I can do something like run webpack on that as needed (just needs to build the files once on a new machine, or be re-run whenever dependencies are updated), and use webpack-dev-server with hot updates to serve up my actual app code, but I need sleep first.

I'm no pro so if this approach would bite me in the ass please let me know before I dig too deep.

@seeliang
Copy link

seeliang commented Sep 30, 2016

Thanks @trueter,
with the babel cacheDirectory set
my rebuild drops form 2.5s to 1.5s

@seeliang
Copy link

seeliang commented Oct 5, 2016

Try cache : true,

Now 1.5s to build 0.6s to rebuild !!

module.exports = {
  cache: true,
  devtool: 'cheap-module-eval-source-map',
  entry: './src/scripts/index.js',
  externals: {

  },

  module: {
    loaders: [
      {
        loader: 'babel-loader',
        exclude: /node_modules/,
        query: {
          presets: ['es2015'],
          cacheDirectory: true
        }
      }
    ]
  },

  output: {

  },

  plugins: [
    new webpack.optimize.UglifyJsPlugin({ output: {comments: false}})
  ],

  resolve: {
    modulesDirectories: [
      'node_modules'
    ]
  }
}`

@echenley
Copy link

echenley commented Oct 6, 2016

@seeliang cache: true is already enabled by default in watch mode https://webpack.github.io/docs/configuration.html#cache. I've noticed with Webpack 1.x the first rebuild takes longer than subsequent rebuilds, which can be a red herring when tweaking your build.

@seeliang
Copy link

seeliang commented Oct 7, 2016

@echenley thanks for the update.

I really not 100% sure why i need cache: true or how it works,
one post mentioned this set

and it did improve my build :)

@seeliang
Copy link

seeliang commented Oct 12, 2016

if you are using babel with lodash

try
https://github.com/lodash/babel-plugin-lodash

@davidnguyen11
Copy link

I am using Happypack & DLL plugin together. Currently, the performance is not so bad. It reduced from more than 15s to 4-5s when it rebuild

@vhpoet
Copy link

vhpoet commented Oct 18, 2016

has anyone tried webpack unsafe caching (another link)? This is also supposed to make incremental builds faster.

@bebraw
Copy link

bebraw commented Dec 6, 2016

hard-source-webpack-plugin might come in handy here.

@nezed
Copy link

nezed commented Dec 14, 2016

Also you can easily improve performance by moving modules that you have no intention of changing into new chunks by specific/extra conditions (e.g. module path or module size) 🔥 🚀

Check the webpack-split-chunks

Example:

    plugins: [
        new ChunksPlugin({
            to: 'vendor',
            test: /node_modules/ // can be function | RegExp | Array[RegExp] 
        })
    ]

@oychao
Copy link

oychao commented Jan 19, 2017

@bdefore Many thanks. You made my day.

kvz added a commit to kvz/lanyon that referenced this issue Mar 23, 2017
@Pines-Cheng
Copy link

my rebuild time is 12s,what's wrong with my project...

@Pines-Cheng
Copy link

after used dll plugin,my project build time is less than 30s,but the rebuild time is still 13s... WTF

@seeliang
Copy link

@Pines-Cheng To optimise rebuild, i think you can start with separating dev build and prod build, try move vendor js files out of build. that is what i can think of for now

@up209d
Copy link

up209d commented Apr 5, 2018

Ran into the slow performance today when I cannot afford the snail speed of rebuilding.

My case was 8s first build (with DLL) and another 8-10s for each rebuild (WTH???). It turned out that webpack was not a guy to blame but babel (babel-loader). Tried to work out with happypack but got no gain.

Well, in the end, it is not actually babel but a babel plugin babel-plugin-styled-components as I am using styled-components stuffs atm. Ver 1.5.0 was like adding 5s to every transformation. The problem was gone when I updated to ver 1.5.1. So now my rebuilds only take 1.5 - 2s.

So my lesson is that, in general, if you get some performance issue with the first build, webpack is most likely the issue origin. If you get speed issue with the re-build, loaders like (babel-loader,sass-loader) are the ones need to be investigated at first. Make sure that you checked all plugins you added to babel transformation, there is a high chance that you will found a solution there.

@sibelius
Copy link

how to fix this?

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