Help, my Angular bundle is growing
Tags: angular, javascript, tutorial, webdev
Published: 2023-01-02 11:00:00

When building an Angular application, things are usually pretty smooth. However, as time goes by and your application is growing, a strange warning may appear:

![Budget exceeded warning example](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/53rbhlpx8yig896c0mde.png)

When first encountered this can raise some questions:

- How can I disable this warning?
- How can I troubleshoot what is making my bundle so big?
- And what on Earth is a *budget*?

Let's answer them!

## The Angular budget

The budget is the term employed by Angular to represent the ultimate size of your application that you will still consider "normal".

For example, you may accept that the bundle of your application will be at most 2MB but more will be strange and over 5MB should not be acceptable.

Thanks to this notion, you can configure this behavior straight into the your project by setting the budget of your application in your `angular.json`:

```jsonp
{
  // ...
  "architect": {
    "build": {
      "configurations": {
        "production": {
          "budgets": [ ]
        }
      }
    }
  }
}
```

However there is more than just one type of budget and you may want to set those threshold for ...

- ... the entire application
- ... any generated bundle
- ... the size of the JavaScript needed for bootstrapping the application
- ... the size of all or any of the scripts
- ... the size of any component style sheet
- ... the size of any file

For each one of those types, you can specify on beyond which threshold you want to have warning or an error.

The threshold values accept a variety of units such as bytes (`b`), kilobytes (`kb`), megabytes (`mb`) or even percentages (`%`) if you specified a baseline value.

For example, here is a budget to have a warning when the size of the app is over 500kB and an error when it is over 50% more than 1MB:

```json
"budgets": [
  {
    "type": "all",
    "baseline": "1mb",
    "maximumWarning": "500kb",
    "maximumError": "150%"
  }
]
```

## Getting rid of the warning, the quick'n dirty way

Knowing this, the easiest and the quickest way not to have this warning is to increase the limit to a higher number.

You could either discuss what it should be in the context of the project you are building, simply set it to an indecent number or even just delete those lines:

```json
"budgets": [
  {
    "type": "initial",
    "maximumWarning": "999mb",
    "maximumError": "999mb"
  },
  {
    "type": "anyComponentStyle",
    "maximumWarning": "999mb",
    "maximumError": "999mb"
  }
],
``` 

This may, however, not really be a solution but more like hiding the problem under the carpet.

## Getting rid of the warning, the proper way

The first step in optimizing something is understanding what can be improved and what is dragging you back.

Bundle optimization is not really different in this case: let's see what our bundle is made of!

### Generating the proper bundle

When you are building your application, Angular is generating several chunks of JS that, together, contain your web page.

Using the production mode, you will also benefit from the Angular compiler's optimizations in order to have a lighter bundle.

A good way to truly understand what your final build will contain is to visualize this optimized bundle and getting ride of what might have been only dev dependencies.

However, if we try to visualize this bundle we wouldn't be seeing any useful because Angular does not generate source maps nor named chunks in production mode.

To solve this, we can simple specify those option to the bundle we would like to inspect:

```sh
~$ ng build --source-map=true --named-chunks=true
```

### Visualizing your bundle

Our bundle generated, we can now get the proper tool to help us inspecting it.

Among others [source-map-explorer](https://github.com/danvk/source-map-explorer) is exactly such a tool and describes itself as such:

> The source map explorer determines which file each byte in your minified code came from. It shows you a treemap visualization to help you debug where all the code is coming from.

This looks promising! Let's grab [the NPM package](https://www.npmjs.com/package/source-map-explorer) and add it to our dev dependencies:

```sh
~$ npm i -D source-map-explorer
```

> You may also want to have everything integrated with Angular. In that case, check the [Builder To Run Source Map Explorer](https://github.com/ngx-builders/source-map-analyzer) which allows you to do so without configuration and from your Angular app using the builder.

At this point, we can also create a new npm script as a shortcut for this operation in the `package.json`:

```jsonc
{
  // ...
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "watch": "ng build --watch --configuration development",
    "test": "ng test",
    "sme": "ng build --source-map=true --named-chunks==true && source-map-explorer dist/<YOU_APP_NAME>/**/*.js"
  },
  // ...
}
```

If everything went well, a new tab in your browser should open itself and display something like this:

![SME example](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/06vdzgv3luvuowdct38p.png)

From this view, you can actually see what is bundled in your app and the size it takes.

> The screenshot is taken from a very lightweight Angular app, yours will surely be much more complex.

### Taking actions

Now that you can actually see what your bundle contains, you can take some actions reduce it and there can be plenty of reasons why it is bigger than expected:

- Maybe [a dependency has a surprisingly big size](https://stackoverflow.com/questions/52827942/ag-grid-bundle-size-is-too-big) and there is other ways to use it that you missed
- Maybe a dependency that should have only be a dev one is a global one
- Etc.

## Good practices

The best behavior to spare you some time and avoid this uncomfortable situation is to take actions beforehand.

When working on your project ...

- ... be careful what dependencies you are using and if you really need them
- ... take advantage of how Angular works to [lazy load](https://angular.io/guide/lazy-loading-ngmodules) your modules and thus lighten the main bundle

You may also want to consider using [standalone components](https://angular.io/guide/standalone-components) as this new paradigm forces you to explicitly declare what your component will be using, allowing you to import only the strict necessary.

---

I hope that you learned something useful there, and wish you a happy coding!

#### Sources

- [Angular.io - Configuring size budgets](https://angular.io/guide/build#configuring-size-budgets)
- [Stack Overflow - WARNING in budgets, maximum exceeded for initial](https://stackoverflow.com/questions/53995948/warning-in-budgets-maximum-exceeded-for-initial)

{% embed https://dev.to/pbouillon %}

---

Photo by <a href="https://unsplash.com/@callump1975?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Callum Parker</a> on <a href="https://unsplash.com/fr/s/photos/heavy?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Unsplash</a>