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
Fix #11700: Widgets with trigger/target bind for removal #11701
Conversation
5192735
to
65a4ecf
Compare
Will review stuff in ~1 week, currently in holiday |
im not sure about this one i think we should destroy it immediately |
OK so just to be sure if I have a however if the Sticky registers the target for removal and I update the Or are you saying when its removed from the DOM the Sticky should be detroyed immediately and not added to |
ahh |
Correct! |
primefaces/src/main/resources/META-INF/resources/primefaces/core/core.widget.js
Outdated
Show resolved
Hide resolved
OK did the following. 1.Renamed to In my Example above with Sticky and Panel if the Panel is removed we are now adding the Sticky to detached widgets which was good! However in |
TBH i wonder if this could destroy some usecases e.g. a OverlayPanel binded to a button |
You are right I will only add it to the components I have seen cause a problem at my client. Namely Sticky and a couple of others. |
e63baba
to
529c5a1
Compare
I removed it from OverlayPanel, ContextMenu, Spotlight, BlockUI but i left it on the others as for things like Draggable, Droppable, Resizable etc the rest it makes no sense not to destroy them when their target is destroyed. as the memory never gets cleaned up. |
TBH im not sure if we should merge this with this change the state is different and can make problems like #11413 11409 |
Understood this one is risky because of the scenarios you mentioned. Is there some way i can make this an option?? The scenario with that SPA app is each time they open a new Tab.... the tab has a Sticky Menu so if they scroll down the page the menu sticks. They close the tab and the Sticky is now holding memory because its target is not in the DOM but it still has a reference to the Even if they re-open a tab they had open that tab creates a new Sticky and new Menu but the original one is holding on to memory. So if they do this for an 8 hour shift the browser eventually crashes. |
will review next days |
i cant speak for sticky for now (never used it) but e.g. take keyfilter inputText and keyFilter are propably on same level in DOM if have it in different container or and you dont update both, you get a memory leak - but its a user error, not a primefaces bug maybe we just add some logging here |
You are totally right about KeyFilter! So here is what I propose to not make this change so drastic. Let me back it up to just |
OK i stripped it down to just Tooltip and Sticky (tooltip already had this behavior for the most part). |
can you also exclude unrelated changes here and create a seperate PR? resizable and dragdop doenst use destroyOnElementRemoval |
Done... Minimal changes now. |
TBH sticky looks very similar to the keyfilter case i mentioned above? |
(im only talking about the destroyOnElementRemoval, overwriting #destroy makes sense anyway and should fix the leak if the user correctly updates both) |
This is easy to replicate using the showcase:
The 6 buttons, all their DIVS and everything inside the toolbar is now being held in memory as "Detached DOM" elements. |
yeah but thats not a "valid case"
if you update form, both are rendered/not-rendered and in the same scope if the scope is different, then you will get a mem leak; exactly the same like with keyfilter. |
OK let me ask them because in that giant SPA app they are dynamically adding and removing Tabs from a TabView and the sticky is inside the tab but it is definitely not being cleaned up properly even thought they have updated the TabView which now has 1 less tab in it. The only way I can get their memory to clean up is to provide them this script which runs on AJAX calls. Basically find all for (key in PrimeFaces.widgets) {
let widget = PrimeFaces.widgets[key];
if (widget && widget.target instanceof jQuery) {
widget.target.off("remove.widget").on("remove.widget", function () {
PrimeFaces.detachedWidgets.push(widget.widgetVar);
});
}
if (widget && widget.trigger instanceof jQuery) {
widget.trigger.off("remove.widget").on("remove.widget", function () {
PrimeFaces.detachedWidgets.push(widget.widgetVar);
});
}
} |
yeah, please ask them, im not sure if my thoughts cover all cases but:
if you take this example and update=someContainer, sticky also wont be automatically reattach to the toolbar as both needs life in the same scope/lifecycle should a component auto reattach to the target component? how are the relations between components, parents, child and so on |
nevertheless, maybe its better to provide a own PR with destroy implementations (also keyfilter, dragdrog and so on first) |
OK i will put this one back to draft for now as you are right components should be updated together and finding out why the Sticky is not being destroyed when the Tab is detroyed is really the core issue. |
i think we should close this for now - it requires much more discussions etc. and this should be done in the ticket. |
Fix #11700: Widgets with trigger/target bind for removal
Wanted to put this out for review and get ideas on name and whether this is the best way to handle it. It feels like it is the cleanest but I am open to names for
bindDomRemovalEvent
etc.