Webpack 5: Progress percentage calculation
Tags: javascript, webpack, webpack5
Published: 2020-02-17 15:41:07

When you build a huge project with webpack, you might notice that progress percentage may get stuck on 66-68% for a long time. This is because by default webpack calculates progress percentage as the ratio of built modules count and total modules count. It's ok at first sight, but the problem is that the total modules count is unknown in advance. Any loader may add a few modules at any moment. Therefore the total modules count is changing during the build and it causes progress percentage jerking.
To solve this problem you can specify an approximate quantity of modules in your project:

```js
new ProgressPlugin({ modulesCount: 10000 });
```

It means that you need to start the build one time, get the total module count somehow and set this value to the plugin settings and then update it manually during the time.
Another solution is to write a script that will count all the files in the project folder and then pass it value to the `modulesCount`-field. This is based on the assumption that one module corresponds to one file, and this is not always the case. Moreover, we can't count `node_modules` correctly because not all of these may be using in your project.
These are dubious solutions...

A year and a half ago, during migrating a huge project to webpack I was thinking that calculating of a progress percentage for the big projects should based on the entry points, not on the modules. There are a lot of entry points in huge projects. Most likely you will split a huge codebase into many entry points, not a single entry point. I made a PR to webpack. Its meaning was to calculate a progress percentage as the ratio of the number of the built entry points to the total number of entry points. The main benefit of this approach is that the total number of the entry points is known in advance and doesn't change during the build.
This PR was merged half taken - it means that the ratio `built/total` will be shown only in a console and will not affect percentage calculation: `252/420` - it means that we have 420 entry points and only 252 was built at this moment.

A couple of days ago another my PR was merged to webpack 5. Its meaning was to choose a percentage calculation strategy. By default, it calculates by number of modules as before. But with `percentBy`-options you can change it. For example, to calculate the progress percentage totally by the number of entry points you may write:

```js
new ProgressPlugin({ percentBy: 'entries' });
```

But it's not the end. while I was writing this post, another idea that seemed to be obvious came to my mind.
I was thinking that we can save total modules count to persistent cache at the end of a build, restore it before a next build will start and initialize `modulesCount`-options of the plugin by this value.
The first compilation will warm the cache, and the next compilations will use and update this value and will show a more realistic percentage, even if we calculate the percentage by modules count.
It is unlikely that between the builds the codebase will change so that the number of modules will be changed so dramatically, well, or it is unlikely that this will happen too often.

This PR was merged today and you can try it with `beta.14` (not released yet) :tada: