Skip to content

HybridManager: improve widget disposal#2085

Open
fschinkel wants to merge 1 commit intoreleases/26.2from
features/fschinkel/26.2/hybrid-manager-dispose-widgets
Open

HybridManager: improve widget disposal#2085
fschinkel wants to merge 1 commit intoreleases/26.2from
features/fschinkel/26.2/hybrid-manager-dispose-widgets

Conversation

@fschinkel
Copy link
Copy Markdown
Member

Add api to HybridManager.ts for widget disposal. Widgets that need to be disposed are collected and the scout.DisposeWidgets-hybrid action is only called once. In addition, listen for destroyed widgets and send a scout.DisposeWidgets-hybrid action as well.
All widgets for which a disposal was scheduled are excluded from property change events in the future as destroyed widgets may no longer be resolved.
Improve performance of DisposeWidgetsHybridAction. The HybridManager adds dispose-listeners to all its widgets and removes them from itself when they are disposed. For this the HybridManager needs to build a new map of widgets, each time its "widgets" property is updated. If a great amount of widgets is disposed, each disposal triggers a rebuild of the HybridManagers "widgets" property. The DisposeWidgetsHybridAction will now remove all widgets that are to be disposed from the HybridManager at once and dispose them afterward. With this the "widgets" property of the HybridManager is only updated once which improves performance when great amounts of widgets are disposed.

379008

@fschinkel fschinkel requested a review from cguglielmo March 9, 2026 13:23
@fschinkel fschinkel self-assigned this Mar 9, 2026
@fschinkel fschinkel force-pushed the features/fschinkel/26.2/hybrid-manager-dispose-widgets branch 4 times, most recently from 411586d to c572753 Compare March 18, 2026 10:36
Add api to HybridManager.ts for widget disposal. Widgets that need to be
disposed are collected and the scout.DisposeWidgets-hybrid action is
only called once. In addition, listen for destroyed widgets and send a
scout.DisposeWidgets-hybrid action as well.
All widgets for which a disposal was scheduled are excluded from
property change events in the future as destroyed widgets may no longer
be resolved.
Improve performance of DisposeWidgetsHybridAction. The HybridManager
adds dispose-listeners to all its widgets and removes them from itself
when they are disposed. For this the HybridManager needs to build a new
map of widgets, each time its "widgets" property is updated. If a great
amount of widgets is disposed, each disposal triggers a rebuild of the
HybridManagers "widgets" property. The DisposeWidgetsHybridAction will
now remove all widgets that are to be disposed from the HybridManager at
once and dispose them afterward. With this the "widgets" property of the
HybridManager is only updated once which improves performance when great
amounts of widgets are disposed.

379008
@fschinkel fschinkel force-pushed the features/fschinkel/26.2/hybrid-manager-dispose-widgets branch from c572753 to a8d6765 Compare March 23, 2026 05:45
Object.entries(removedWidgets).forEach(([id, widget]) => this._triggerWidgetRemove(id, widget));
Object.entries(addedWidgets).forEach(([id, widget]) => {
this._installHybridManagerWidget(widget, id);
// trigger widgetAdd event
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no need to add a comment if the method call is meaningful enough and basically the same as the comment

}
// get all widgets that need to be disposed
Map<String, IWidget> widgets = hybridManager().getWidgets().entrySet().stream()
.filter(entry -> data.getIds().contains(entry.getKey()) && entry.getValue() != null)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not loop over data.getIds() and call getWidgetById()? It would be faster because looping over getWidgets() and using getIds().contains is O(n^2)

// collect remote ids, transfer widget ids to this._disposeWidgetsScheduledWidgetIds and reset next batch
const remoteIds: string[] = [];
for (const widget of [...this._disposeWidgetsNextBatch]) {
remoteIds.push(widget.__remoteId);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • widget.__removeId is null for forms, because _uninstallHybridManagerWidget is called before the microtask runs
  • Forms are disposed on server, do we even need a destroy listener for forms?

* Set of ids that were scheduled in former batches.
* See {@link #_callDisposeWidgets} for more information.
*/
protected _disposeWidgetsScheduledWidgetIds = new Set<string>();
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the name is a little cumbersome... Maybe call it widgetIdsBeingDisposed and the other one _widgetsToBeDisposed?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants