formio / angular

JSON powered forms for Angular
https://formio.github.io/angular-demo
MIT License
644 stars 472 forks source link

Multiple FormioComponent instances retained in memory [Question] #799

Open SGhantous opened 3 years ago

SGhantous commented 3 years ago

My company uses Formio to render forms, and recently one of our clients noticed some odd behavior with our application. I did some investigation to determine what the issue could be, and while doing so noticed that whenever we open a dialog that contains the FormioComponent a new instance of the component is created, but when the dialog is closed it does not get destroyed.

I created as bare bones an application as I could to reproduce the issue so as to eliminate our application being the source of the problem. All it contains is a button that when clicked opens a dialog containing the FormioComponent.

<formio [form]="form" [options]="options"></formio>

form: Object = {
    components: []
  };

  options: Object = {
    submitMessage: "",
    disableAlerts: true,
    noAlerts: true
  }

Below is a snapshot before I open the dialog containing the FormioComponent:

Before Opening Dialog

Here is after opening and closing the dialog once:

Open and Close Once

Here is after opening and closing another two times:

Open and Close Three Times

And a comparison between Snapshot 1 and Snapshot 3 that shows none of the FormioComponents being deleted:

Snapshot Comparison

There are Detached HTMLDivElements that are not getting deleted that appear to be reachable through Formio:

Detached Divs

I'm wondering if anyone else has seen this issue before and what they did to fix it.

Below is the link to the github for anyone that wishes to reproduce the issue for themselves. I was not able to get a stackblitz to work with @formio/angular.

https://github.com/SGhantous/Angular-Formio-Demo

gitmiro commented 2 years ago

@SGhantous

We've got the same issue. Memory-usage is stacking up to the skies. Have you found a solution for your use case?

jeriah-formio commented 9 months ago

Closing this thread as it is outdated. Please re-open if it is still relevant. Thank you for your contribution!

guneraykut commented 3 weeks ago

We face same problem. JS VM heap memory goes skies and then chrome tab crash with OOM error. @jeriah-formio

lane-formio commented 2 weeks ago

@guneraykut formio/angular and formio.js versions?

guneraykut commented 2 weeks ago

@lane-formio

Here are the versions:

"angular-formio": "4.11.5", "@formio/angular": "5.2.2", "@formio/angular-material": "2.0.0", Angular: 14.2.10 Node: 18.0.0

Thank you.

enginozkaya commented 1 week ago

Hi @lane-formio, In addition to @guneraykut case; (we are on the same team) Our form builder design object (formDesign) is around 8-9mb and every time we load the object to the form-builder and trigger refresh with EventEmitter. memory increases. even if we empty cache and hard reload the page, memory stays there.

this.triggerRefresh.emit();

<form-builder [form]="formDesign" [options]="formIoConfiguration" [refresh]="triggerRefresh"

More info about our formDesign object: We are fetching formdesign object from our API and giving it to the form-builder. We have couple inline base64 image contents in our formdesign and somehow those contents stays in the memory as a string and never cleared by the chrome. (only way to clear is that we close the tab and open a new one) Every time we load the design, memory increse by 200mb or so. and when we hit the 3000mb, chrome crashes.

here is the memory snapshot looking: image

Update: We are using Angular@14, @formio/angular@5.2.2. but i replicated the issue with Angular 17 and @formio/angular@7.5.0 and got the same results. here is package.json:

{
  "name": "angular-formio3",
  "version": "0.0.0",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "watch": "ng build --watch --configuration development",
    "test": "ng test"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "^17.3.0",
    "@angular/common": "^17.3.0",
    "@angular/compiler": "^17.3.0",
    "@angular/core": "^17.3.0",
    "@angular/forms": "^17.3.0",
    "@angular/platform-browser": "^17.3.0",
    "@angular/platform-browser-dynamic": "^17.3.0",
    "@angular/router": "^17.3.0",
    "@formio/angular": "^7.5.0-rc.6",
    "@formio/js": "^5.0.0-rc.97",
    "rxjs": "~7.8.0",
    "tslib": "^2.3.0",
    "zone.js": "~0.14.3"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "^17.3.11",
    "@angular/cli": "^17.3.11",
    "@angular/compiler-cli": "^17.3.0",
    "@types/jasmine": "~5.1.0",
    "jasmine-core": "~5.1.0",
    "karma": "~6.4.0",
    "karma-chrome-launcher": "~3.2.0",
    "karma-coverage": "~2.2.0",
    "karma-jasmine": "~5.1.0",
    "karma-jasmine-html-reporter": "~2.1.0",
    "typescript": "~5.4.2"
  }
}

and example code:

app.component.html:

<form-builder
  [form]="form"
  [rebuild]="rebuildEmitter.asObservable()"
></form-builder>

app.component.ts:

export class AppComponent implements OnInit {
public rebuildEmitter: Subject<object> = new Subject<object>();
  title = 'angular-formio3';
  options= {</regular example builder configuration object/>}
  form= {</big form design object with 10 big inline base64 images inside of content component/>}

  public ngOnInit(): void {
  setInterval(()=> {
  this.rebuildEmitter.next(this.options);
  }, 2000);
  }
}