-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DRAFT: feat(memory-leak): add elements cleanup for did-intersect modifier #1078
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,4 +23,9 @@ export default class ObserverManagerService extends Service { | |
willDestroy() { | ||
this._admin.destroy(); | ||
} | ||
|
||
removeElement(element) { | ||
this._admin.elementRegistry.removeElement(element); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
https://github.com/snewcomer/intersection-observer-admin/blob/master/src/index.ts#L22 |
||
this._admin.registry.removeElement(element); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Where is There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we perhaps need to make updates to the underlying class to expose a public method for this kind of cleanup? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We'll see, I'd imagine that that's what There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yea, it seems like maybe there's some extra steps missing from the |
||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import { module, test } from 'qunit'; | ||
import { setupRenderingTest } from 'ember-qunit'; | ||
import { render } from '@ember/test-helpers'; | ||
import hbs from 'htmlbars-inline-precompile'; | ||
import sinon from 'sinon'; | ||
|
||
module( | ||
'Integration | Modifier | did-intersect without mocks', | ||
function (hooks) { | ||
setupRenderingTest(hooks); | ||
|
||
hooks.beforeEach(function () { | ||
this.enterStub = sinon.stub(); | ||
this.exitStub = sinon.stub(); | ||
this.maxEnter = 1; | ||
this.maxExit = 1; | ||
|
||
this.observerManagerService = this.owner.lookup( | ||
'service:ember-scroll-modifiers@observer-manager', | ||
); | ||
}); | ||
|
||
test('it removes elements from the registry on modifier cleanup', async function (assert) { | ||
let removedElementsCount = 0; | ||
let originalRemoveElement = this.observerManagerService.removeElement; | ||
const observerManagerService = this.observerManagerService; | ||
|
||
observerManagerService.removeElement = function removeElementExt( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this would be better accomplished with |
||
...args | ||
) { | ||
removedElementsCount++; | ||
originalRemoveElement.call(observerManagerService, ...args); | ||
}; | ||
for (let index = 0; index < 50; index++) { | ||
await render( | ||
hbs`<div {{did-intersect onEnter=this.enterStub onExit=this.exitStub}}> | ||
<span>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</span> | ||
</div>`, | ||
); | ||
} | ||
|
||
assert.strictEqual( | ||
removedElementsCount, | ||
49 * 2, // once for the element, once for a window object | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should also assert against the underlying IntersectionObserverAdmin to ensure its registry gets cleaned up and prove that your implementation of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Initially I wanted to inspect the count of elements, but the registry is a WeakMap which doesn't have a length/count method. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder if you could do something clever like grab a reference to one of the elements (which are the keys to the registry, I think?) and then assert that a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I did think about that but then the issue is that you'd probably want to make sure that you no longer hold this reference yourself, so it'd just get funky 👯 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What I'm thinking is that you grab the reference only in the test. The sinon spy for |
||
); | ||
}); | ||
}, | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why
window
cleanup here? This modifier doesn't explicitly subscribe towindow
at all.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I know it's weird. I'll be taking this to the
interesction-observer-admin
next.I'd hope that this addon won't need these changes actually, since the issue lies on the dependency it uses.
But since I've had this experimental patch already, I decided I'd open a PR to showcase the issue. And frankly, I didn't think I'd get your attention so fast 😅
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Heh! Well, I may not have had a lot of time for active development, but I very much appreciate contributions and will do my best to be responsive (though I'm on vacation for a week starting Saturday, FYI). :)
I definitely think some fixes to the underlying dependency make sense in the context of this issue. If this is a workaround until you can get those fixes in, can you add a brief comment explaining why the workaround is needed, and then we can remove it once you land fixes upstream?