angular-extensions / elements

Lazy load Angular Elements (or any other web components / custom elements ) with ease!
https://angular-extensions.github.io/elements/
MIT License
315 stars 40 forks source link

Remove added listeners on load and error events in service destructor #134

Closed Arooba-git closed 1 year ago

Arooba-git commented 1 year ago

Hello 👋 As part of our project, we are using Facebook's new Memlab tool to detect memory leaks in SPA applications and its libraries. While running the tool and analyzing the code of angular-elements, we saw that your project does a very good job of ensuring that all async operations are cancelled when components destroy. However, as per Memlab execution results, we found 2 dangling event listeners that were causing memory to leak (screenshots below).

[before]

Screen Shot 2023-02-02 at 5 26 22 AM

Hence we added the fix by removing the listeners on service unload, and you can see the heap size and # of leaks reducing noticeably:

Screen Shot 2023-02-02 at 5 39 54 AM

Note 1. Host listener is used to ensure that ngOnDestroy is called not only when the class destroy, but also when the page refreshes, tab or browser closes or the user navigates away from the page[1]

Note 2. Static property is used to avoid losing the context of the correct ‘this’ in case any nesting changes are made to the enclosing function in future.

Note 3. Removing the added listener using the conventional method of removeEventListener would require assigning the ‘script’ variable to a class property and using that in the destructor function, but we found our current implementation[2] much quicker/less verbose.

We performed user testing after the fix, and all components function as before.

You can analyze this and other potential leak sources, if you like, by running Memlab with a scenario file covering the maximum # of use cases.

Following is a sample of the scenario file we used (it needs to be a .js file but attaching here in .txt form): angular-elements-scenario-memlab.txt

Note that some other reported leaks (in Memlab) originated from Angular's internal objects, hence were ignored.

References: [1] https://wesleygrimes.com/angular/2019/03/29/making-upgrades-to-angular-ngondestroy.html [2] https://css-tricks.com/using-abortcontroller-as-an-alternative-for-removing-event-listeners/

tomastrajan commented 1 year ago

@Arooba-git hey there!

thank you very much for your contribution, i have not noticed it and did a relatively large upgrade and refactor towards Angular 15 support, would be still very interested in this fix, could you pleasy try to rebase it on the most recent version?

Thank you!

Arooba-git commented 1 year ago

@Arooba-git hey there!

thank you very much for your contribution, i have not noticed it and did a relatively large upgrade and refactor towards Angular 15 support, would be still very interested in this fix, could you pleasy try to rebase it on the most recent version?

Thank you!

Sure, let me update it. 👍