fix: use function reference to add & remove listener #219
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This pull request fixes a memory leak from incorrect usage of
removeEventListener
- see reproduction steps below.The problem is that
_onVisibilityChange
is not provided as a reference toaddEventListener
/removeEventListener
(so that it can be matched and removed). The inline arrow functions that are provided as event handlers are actually different references so they don't get removed. Every time alottie-player
element gets removed from the DOM, itsvisibilitychange
listener (the arrow function & its closure) doesn't get cleaned and leads to memory leaks.Reproduction
You can reproduce it with this sample app: https://codesandbox.io/s/summer-brook-szmng7
Solutions:
_onVisibilityChange
to an arrow function (sothis
gets bound correctly to declaration context and always refers to the "LottiePlayer" instance) and provide its reference as an event handler. This keeps the reference the same and it can get removed properly._onVisibilityChange
as is, but we need to bindthis
to it in the constructor withthis._onVisibilityChange = this._onVisibilityChange.bind(this);
. Again, the arrow functions should be removed from event handling and usethis._onVisibilityChange
as a reference there.Note:
readonly
isn't needed for this fix, it was added to satisfy an eslint warning (@typescript-eslint/prefer-readonly
)