-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Attempt memory leak fix from using magics #2832
Conversation
Do line 16-20 need to be inside the get definition? Can they just be moved to line 14 (inside the foreach bit outside the property definition?). About redefining a magic, i don't think Alpine supporters it: magics are injected once when a component is evaluated the first time and those are the implementations that will be used. Anything defined after that moment is not visible to the component so I don't think it's a concern. |
@SimoTod I think they need to be within get declaration to be lazily evaluated, so I think it would work if it was defined outside the get, but that would raise the overhead of using anything that uses injectMagics but doesn't actually use magics. I'm going to think for a few minutes about other ways to lazily evaluate though, since I'm not sure that calling the |
Edited: a previous version of this comment had a logic error in the memoization that caused a test failure, I fixed it and updated the comment to reflect newer information. I'm worried about this PR breaking something because it assumes that the magic's export function injectMagics(obj, el) {
Object.entries(magics).forEach(([name, callback]) => {
let memoizedUtilities = null;
function getUtilities() {
if (memoizedUtilities) {
return memoizedUtilities;
} else {
let [utilities, cleanup] = getElementBoundUtilities(el)
memoizedUtilities = {interceptor, ...utilities}
onElRemoved(el, cleanup)
return memoizedUtilities;
}
}
Object.defineProperty(obj, `$${name}`, {
get() {
return callback(el, getUtilities());
},
enumerable: false,
})
})
return obj
} |
maybe safer for some types of consumption
I updated the PR to have the last comment's version of the patch, both commits on the branch fix the memory issue but in different ways, maybe the second commit is safer to roll out. |
Opened an issue for the underlying behavior problem to track independently of potential fixes: #2847 |
Thanks for the PR! We're going to leave this one open for now so Caleb can have a close look at it when he gets the chance. He agrees that the current implementation is inefficient so wants to look at it in detail. |
Sorry, hit close instead of comment! 🤦♂️ |
As a further follow up, we're going to leave this PR open for now, as Caleb wants to review it in detail, but currently doesn't have time whilst working on Livewire V3. |
Thank you so much for this fix @byronanderson! |
From #2847 :
We have two thoughts about potential fixes for this behavior in
injectMagics
function:We have an implementation for option 1 (this PR), but that assumes that the
magic
plugin function is only called once for a magic.I.E. If we had a plugin that did something like this:
The existing implementation would support this behavior, and option 2 would mitigate this downside, but require mutation.js to have a 'removeOnElRemovedCallback' kinda like this that we didn't quite know how to implement in fullness:
Sorry I couldn't figure out how to get codesandbox to host my fixed version to illustrate :(