I've got SmartClient Version: v9.0_2013-07-03/LGPL Development Only (built 2013-07-03), and am using Chrome 31.0.1650.57 on OS X 10.9.
I'm developing an MVP GWT 2.5.1 app where I'm "swapping views" by switching out one Composite widget on the RootPanel for another, using the usual RootPanel.get().clear() and RootPanel.get().add(newWidget) to remove and add, respectively. The hybrid view-widgets may or may not actually contain SmartGWT widgets, but the project as a whole inherits com.smartgwt.SmartGwt.
The first composite widget contains a TextBox. It listens for the Enter keypress, which triggers the swap. Nothing too fancy:
The problem is that there is a DOM memory leak (see attached screenshot): after RootPanel.get().clear() is called, the old composite widget is stuck in the detached DOM tree because the HTMLInputElement for the TextBox is referenced by isc.Event.lastEvent.nativeKeyTarget is ISC_Core.js. This is problematic because the first view-widget hybrid potentially contains a large amount of data, which takes up heap memory. This memory is not cleared once the view is switched.
There were other hanging references from ISC_Core.js to elements of the first view. After tracking them all down, I found that calling the following native method call during the loading of the new view helps free the used heap memory by pointing ISC_Core.js references to the window:
My question is this: is there a more appropriate way that I should be using either SmartGWT, GWT, or Javascript, so that DOM leaks from the first view's widgets are eliminated?
I'm developing an MVP GWT 2.5.1 app where I'm "swapping views" by switching out one Composite widget on the RootPanel for another, using the usual RootPanel.get().clear() and RootPanel.get().add(newWidget) to remove and add, respectively. The hybrid view-widgets may or may not actually contain SmartGWT widgets, but the project as a whole inherits com.smartgwt.SmartGwt.
The first composite widget contains a TextBox. It listens for the Enter keypress, which triggers the swap. Nothing too fancy:
Code:
getDisplay().getTextBoxForKeyPresses().addKeyPressHandler(new KeyPressHandler() {
public void onKeyPress(KeyPressEvent event) {
if (event.getNativeEvent().getKeyCode() == KeyCodes.KEY_ENTER) {
swapWidgets(); // clear RootPanel and add new widget
}
}
});There were other hanging references from ISC_Core.js to elements of the first view. After tracking them all down, I found that calling the following native method call during the loading of the new view helps free the used heap memory by pointing ISC_Core.js references to the window:
Code:
public static native void clearPrevious() /*-{
$wnd.isc.Event.lastClickTarget = window;
$wnd.isc.Event.lastEvent.nativeKeyTarget = window;
if ($wnd.isc.Event.mouseDownEvent) {
$wnd.isc.Event.mouseDownEvent.nativeKeyTarget = window;
$wnd.isc.Event.mouseDownEvent.nativeTarget = window;
}
}-*/;