Angular-cli: Memory footprint of angular 7

Created on 14 Jan 2019  Β·  13Comments  Β·  Source: angular/angular-cli

🐞 bug report

Affected Package

Unfortunately, I cannot tell precisely, which package of @angular is causing the behavior.

Is this a regression?


Yes, the memory footprint raised a lot after upgrading from angular 6.1.0 to angular 7.1.3.

Description

A clear and concise description of the problem...
After upgrading a quite large application (about 300-400 components and a lot of providers, @ngxs and @ngrx) from angular+angular/material from v6 to v7 without chaning the rest of the code (only occurences that caused compilation failures) I noticed a lot of memory overhead.

Comparing two memory dumps from app before and after upgrade it looks like this:

Memory dump of @angular v7 app
v7
Memory dump of @angular v6 app
v6

These heap snapshots were taken after logging in to both apps, navigating to a page with a lot of stuff going on and doing a refresh in both instances. After the initial load finished, I took the snapshots.

Comparing the two heap sizes, the heap size difference between v6 and v7 is always the difference of (string) constants in memory.

Did anyone notice the same behavior already? Is it something renderer or compiler specific? I don't know, how to isolate the problem.

πŸ”¬ Minimal Reproduction


As this problem is only notable for a large application, there is no "minimal" repro. I also cannot publish the code of the faulty app, as it is a productive app.

πŸ”₯ Exception or Error

See Description

🌍 Your Environment

Angular Version:


> ng "version"


     _                      _                 ____ _     ___
    / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
   / β–³ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
  / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
 /_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
                |___/


Angular CLI: 7.1.2
Node: 8.9.1
OS: win32 x64
Angular: 7.1.3
... animations, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router

Package                            Version
------------------------------------------------------------
@angular-devkit/architect          0.11.2
@angular-devkit/build-angular      0.11.4
@angular-devkit/build-ng-packagr   0.11.2
@angular-devkit/build-optimizer    0.11.4
@angular-devkit/build-webpack      0.11.4
@angular-devkit/core               7.1.2
@angular-devkit/schematics         7.1.2
@angular/cdk                       7.1.1
@angular/cli                       7.1.2
@angular/flex-layout               7.0.0-beta.19
@angular/material                  7.1.1
@angular/material-moment-adapter   7.1.1
@ngtools/json-schema               1.1.0
@ngtools/webpack                   7.1.4
@schematics/angular                7.1.2
@schematics/update                 0.11.2
ng-packagr                         4.4.5
rxjs                               6.3.3
typescript                         3.1.6
webpack                            4.23.1

Anything else relevant?


If anyone has an idea how to isolate the problem itself, I will kindly try to do so!

I opened up a stackoverflow post around one month ago, but nobody was able to help me yet. That's why I am creating this ticket. See: https://stackoverflow.com/questions/53848710/angular-7-memory-footprint-leaks

devkibuild-angular memorperformance

Most helpful comment

@skreborn

If you have a deeper look into the dumps you can see that these strings are some kind of JIT-compiled code. I don't know much about the internal compiler procedures, but check the size comparison of the objects. I think this is no expected behavior, that's why I thought it's better to report an issue.

Left side: angular 6 app, right side: angular 7 app
string-comparison

I searched for the same parent object (SingleTitleComponent.html:92) to allow comparison.

All 13 comments

Just to note, this is the same even for a production build (with AOT).

@drakenfly Since you are unable to share anything, I suggest you actually check the strings that are in the heap at that time and diff them between v6 and v7, see what appears new. Perhaps these strings are from modules you'd normally lazy load? Are they just garbage, or maybe duplicates? This will probably help tell why they appear in the first place.

@skreborn

If you have a deeper look into the dumps you can see that these strings are some kind of JIT-compiled code. I don't know much about the internal compiler procedures, but check the size comparison of the objects. I think this is no expected behavior, that's why I thought it's better to report an issue.

Left side: angular 6 app, right side: angular 7 app
string-comparison

I searched for the same parent object (SingleTitleComponent.html:92) to allow comparison.

@drakenfly That is indeed a huge difference in size! Are those both built with the same configuration (AOT, build-optimizer, production mode)?

Yes, they are both built with the same configuration. On the last screenshot I posted it was without build-optimizer, non-AOT and no production mode enabled.
Back then I even noticed this behavior only because the animations on the page were getting very laggy (Chrome@ 71.0.3578.98) during development.

Comparing v6 and v7 with these settings

          "configurations": {
            "production-cb": {
              "fileReplacements": [
                {
                  "replace": "apps/webapp/src/environments/environment.ts",
                  "with": "apps/webapp/src/environments/environment.prod.cb.ts"
                }
              ],
              "optimization": true,
              "outputHashing": "all",
              "sourceMap": false,
              "extractCss": true,
              "namedChunks": false,
              "aot": true,
              "extractLicenses": true,
              "vendorChunk": false,
              "buildOptimizer": true,
              "budgets": [ ... ]
            },

by running "ng serve -- --configuration=production-cb" (and --port=4600|4700, depending on the project to run both simultaneously) it looks like this:
comparison-prod

I can remember it was worse in december, but I also updated @angular-devkit/build-angular to 0.12.1 since then. I tried it with the old version (0.11.0) right now, but it seems to be almost the same.

So, I think it's an issue in the JIT compiler.

I will try to create a repro next week!

@drakenfly did you have a chance to come up with a repro ?

Unless we have one shortly, the issue will be closed. Thanks.

Hi! I've tried a lot of things and I think I was able to isolate this behaviour. It comes from the styles that are referenced in the component metadata!

But I have to say, that I'm not sure if this problem is within angular, the compiler or @angular/cli.

I've created a demo repository: https://github.com/drakenfly/angular-6-vs-7-memory-problems

Terminal 1:

  • cd angular-6
  • npm i
  • npm start

Terminal 2:

  • cd angular-7
  • npm i
  • npm start

Wait for compilation, then open your browser with two tabs, http://localhost:4600, http://localhost:4700, wait for page load(s) and create a memory dump in both tabs.

memory-compare

As you can see, the memory size of the same component factory has twice the size.
The demo component has the same files in both projects (angular 6 and angular 7).

@drakenfly, thank you for the reproduction!

This is a result of inline CSS source maps. In v6 the styles have references to a .css.map file; in v7 the source map for the CSS is inlined in the string in the browser.

Given that this only happens in JIT, this is an Angular CLI toolchain bug, not a framework bug. In AOT mode the optimizer removes the sourcemaps, and in fact the v7 code in AOT appears to use slightly less memory.

@drakenfly, firstly I'd like to thank you for the excellent reproductions you provided πŸ‘.

As highlighted by @alxhub, the issue is related to the inlining of CSS sourcemaps for components. While indeed previously we did use sourceMappingURL in component styles. The browser was unable to recognize and load these sourcemaps and the fix for this was to make the CSS sourcemaps inlined.

A quickway to see what I am saying above is if you look at the style panel in the devtools.

In version 6 you'd see:
image

In version 7 you'll see:
image

Note the file path on the right which for version 7 it points to the original files, while for version 6 there is none.

If you don't wish to use CSS Sourcemaps, you can disable them by adding the below in your angular.json

 "sourceMap": {
       "scripts": true,
       "styles": false
},

It is also important to note, that these sourcemaps are not meant to be used when you are going to deploy the application on production but rather for debugging. If you'd like to use sourcemaps for your deployed applications you should opt for hidden sourcemaps, which internally it take cares of not creating inlined sourcemaps and sourceMappingURL.

More information about this in this article: https://blog.angularindepth.com/debug-angular-apps-in-production-without-revealing-source-maps-ab4a235edd85

@alan-agius4, many thanks for your appreciation and the detailed explanation!

In this case, I think we will just turn off stylesheet source maps and re-enable them if necessary.

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

_This action has been performed automatically by a bot._

Was this page helpful?
0 / 5 - 0 ratings

Related issues

JanStureNielsen picture JanStureNielsen  Β·  3Comments

jbeckton picture jbeckton  Β·  3Comments

MateenKadwaikar picture MateenKadwaikar  Β·  3Comments

gotschmarcel picture gotschmarcel  Β·  3Comments

naveedahmed1 picture naveedahmed1  Β·  3Comments