Revision history [back]

click to hide/show revision 1
initial version

asked 2013-02-18 08:44:03 +0800

cvarona gravatar image cvarona

Possible DOM leak upon closing a tab (II)

Hi again,

when I raised the question concerning dom nodes leaked when closing a tabbox' tab by means other than clicking on its close button I forgot to mention that, should the form to be loaded into the enclosing panel take long enough as to make a progress box appear, the box itself is likely to be leaked as well (though not always).

The example in my previous question can be easily modified to make it possible to test this (you might need several tries, but sooner or later it will do):

<window title="My First Window" border="normal" width="600px">
    <zscript>
    import org.zkoss.zk.ui.event.*;

    int cnt = 0;

    public class YesNo implements EventListener {

        private Tab _tab;

        public YesNo( Tab tab ) {
            _tab = tab;
        }

        public void onEvent( Event event ) {        
            if( "onYes".equals( event.getName() ) ) {
                _tab.onClose();
            }
        }
    }

    public class AreYouSure implements EventListener {

        private Tab _tab;

        public AreYouSure( Tab tab ) {
            _tab = tab;
        }

        public void onEvent( Event event ) {
            event.stopPropagation();
            Messagebox.show( "Are you sure?", "Beware !", Messagebox.NO | Messagebox.YES, Messagebox.EXCLAMATION, Messagebox.NO, new YesNo( _tab ) );
        }
    }

    public class DirectClose implements EventListener {

        private Tab _tab;

        public DirectClose( Tab tab ) {
            _tab = tab;
        }

        public void onEvent( Event event ) {
            _tab.onClose();
        }
    }

    public void newTab( long delay ) {

        if( delay > 0 ) {
            Thread.currentThread().sleep( delay );
        }

        Tab tab = new Tab( String.valueOf( cnt ) );
        tab.setClosable( true );
        tab.addEventListener( "onClose", new AreYouSure( tab ) );
        tabbox.getTabs().appendChild( tab );

        Tabpanel tabpanel = new Tabpanel();
        Button b = new Button( "Close" );
        b.setParent( tabpanel );
        b.addEventListener( "onClick", new DirectClose( tab ) );

        tabbox.getTabpanels().appendChild( tabpanel );
        cnt++;        
    }
    </zscript>
    <hlayout>
        <button label="New tab" onClick="newTab( 0 );" />
        <button label="New tab, with delay" onClick="newTab( 2000 );" />
    </hlayout>
    <tabbox id="tabbox">
        <tabs />
        <tabpanels />
    </tabbox>
</window>

My zk.xml specifies the following:

<device-config>
    <device-type>ajax</device-type>
    <server-push-class>org.zkoss.zkmax.ui.comet.CometServerPush</server-push-class>
    <unavailable-message><![CDATA[
    <p style="color:red">Sorry, JavaScript must be enabled.</p>
    <p style="color:red">Lo sentimos, JavaScript debe de estar permitido.</p>
    ]]>
    </unavailable-message>

    <embed>
        <script type="text/javascript">
            AU_progressbar = function (id, msg)
            {
                Boot_progressbox(id, msg, 0, 0, true, true);
            };
        </script>
    </embed>
    <timeout-uri>session_expired.zul</timeout-uri>
</device-config>

and this is how a leaked progress box looks like:

progress box leaked

Although the amount leaked in this test case might look unimportant (less than 1MB each time), in a real scenario the actual amount depends on the document fragments being leaked, i.e., in the forms being loaded (usually far more complex than the one depicted in this example). As forms are loaded and this discarded, this little leak results quite severe.

With kind regards

César Varona

Possible DOM leak upon closing a tab (II)

Hi again,

when I raised the question concerning dom nodes leaked when upon closing a tabbox' tab by means other than clicking on its close button I forgot to mention that, should the form to be loaded into the enclosing panel associated tabpanel take long enough as to make a progress box appear, the box itself is likely to be leaked as well (though not always).

The example in my previous question can be easily modified to make it possible to test this (you might need several tries, but sooner or later it will do):

<window title="My First Window" border="normal" width="600px">
    <zscript>
    import org.zkoss.zk.ui.event.*;

    int cnt = 0;

    public class YesNo implements EventListener {

        private Tab _tab;

        public YesNo( Tab tab ) {
            _tab = tab;
        }

        public void onEvent( Event event ) {        
            if( "onYes".equals( event.getName() ) ) {
                _tab.onClose();
            }
        }
    }

    public class AreYouSure implements EventListener {

        private Tab _tab;

        public AreYouSure( Tab tab ) {
            _tab = tab;
        }

        public void onEvent( Event event ) {
            event.stopPropagation();
            Messagebox.show( "Are you sure?", "Beware !", Messagebox.NO | Messagebox.YES, Messagebox.EXCLAMATION, Messagebox.NO, new YesNo( _tab ) );
        }
    }

    public class DirectClose implements EventListener {

        private Tab _tab;

        public DirectClose( Tab tab ) {
            _tab = tab;
        }

        public void onEvent( Event event ) {
            _tab.onClose();
        }
    }

    public void newTab( long delay ) {

        if( delay > 0 ) {
            Thread.currentThread().sleep( delay );
        }

        Tab tab = new Tab( String.valueOf( cnt ) );
        tab.setClosable( true );
        tab.addEventListener( "onClose", new AreYouSure( tab ) );
        tabbox.getTabs().appendChild( tab );

        Tabpanel tabpanel = new Tabpanel();
        Button b = new Button( "Close" );
        b.setParent( tabpanel );
        b.addEventListener( "onClick", new DirectClose( tab ) );

        tabbox.getTabpanels().appendChild( tabpanel );
        cnt++;        
    }
    </zscript>
    <hlayout>
        <button label="New tab" onClick="newTab( 0 );" />
        <button label="New tab, with delay" onClick="newTab( 2000 );" />
    </hlayout>
    <tabbox id="tabbox">
        <tabs />
        <tabpanels />
    </tabbox>
</window>

My zk.xml specifies the following:

<device-config>
    <device-type>ajax</device-type>
    <server-push-class>org.zkoss.zkmax.ui.comet.CometServerPush</server-push-class>
    <unavailable-message><![CDATA[
    <p style="color:red">Sorry, JavaScript must be enabled.</p>
    <p style="color:red">Lo sentimos, JavaScript debe de estar permitido.</p>
    ]]>
    </unavailable-message>

    <embed>
        <script type="text/javascript">
            AU_progressbar = function (id, msg)
            {
                Boot_progressbox(id, msg, 0, 0, true, true);
            };
        </script>
    </embed>
    <timeout-uri>session_expired.zul</timeout-uri>
</device-config>

and this is how a leaked progress box looks like:

progress box leaked

Although the amount leaked in this test case might look unimportant (less than 1MB each time), in a real scenario the actual amount depends on the document fragments being leaked, i.e., in the forms being loaded (usually far more complex than the one depicted in this example). As time goes by and forms are loaded and this discarded, eventually discarded this little leak results grows quite severe.big.

With kind regards

César Varona

Support Options
  • Email Support
  • Training
  • Consulting
  • Outsourcing
Learn More