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 #142

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; all components function as before. We also executed the project's lib and demo tests and all test suites are passing.

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/

Arooba-git commented 1 year ago

@tomastrajan This PR is created on the latest code as of now. As the previous PR was created on my fork's master branch, I couldn't rebase it, hence the new one.

tomastrajan commented 1 year ago

@Arooba-git thank you very much for your contribution!