Mats Bryntse
14 January 2013

Improving Siesta performance

It was recently brought to our attention that Siesta performed poorly if you had a test producing several hundred assertions. […]

It was recently brought to our attention that Siesta performed poorly if you had a test producing several hundred assertions. We did a quick investigation and found that the Ext JS grid was doing a re-layout of the grid everytime a new assertion record was added to the store. This meant loads and loads of code was being executed for no reason. We’ve now put a fix in place, and more importantly – a test to prove this doesn’t happen again. Here’s how we did it:

First we wrote a simple test to detect this bug by counting the amount of layouts performed in the entire Siesta UI before and after manipulating the UI. You can also use tests like this one in your Sencha applications to make sure your containers aren’t doing too many expensive layout cycles. Note that we’re actually testing and rendering an entirely new and sandboxed copy of Siesta inside of Siesta.

StartTest(function(t) {
    // This starts a new Siesta instance in the test iframe
    t.getHarness([
        '601_siesta_ui_failing.t.js'
    ]);

    t.diag('Verify no layouts occur due to assertions added to a store');

    var before = 0;
    var after = 0;

    t.chain(
        { waitFor : 'rowsVisible', args : 'testgrid' },

        // Make sure UI is loaded, rendered and ready
        { waitFor : 1000 },

        function(next) {
            Ext.each(Ext.ComponentQuery.query('container'), function(c) {
                before += c.layoutCounter;
            });

            // Adding an assertion should not cause a relayout
            var grid = Ext.ComponentQuery.query('assertiongrid')[0];
            grid.store.add(new grid.store.model());

            // Updating a test record should not cause a relayout
            var testgrid = Ext.ComponentQuery.query('testgrid')[0];
            testgrid.getRootNode().firstChild.set('title', 'foo');

            Ext.each(Ext.ComponentQuery.query('container'), function(c) {
                after += c.layoutCounter;
            });

            t.is(after, before, 'No additional layouts caused');
        }
    );
});

Below is the patch added to the AssertionGrid class, which prevents an internal method from being called (ultimately triggering a relayout):

viewConfig : {
     onAdd : function() {
           this.refreshSize = Ext.emptyFn;
           var val = Ext.grid.View.prototype.onAdd.apply(this, arguments);
           this.refreshSize = Ext.grid.View.prototype.refreshSize;
           return val;
     }
}

This patch will be included in the next release and should speed up your test suite when you use the Siesta UI. Thanks to Brian Moeskau at Extensible for pointing this out to us!

Mats Bryntse

Siesta Tips 'n tricks