Sencha Con 2013: Ext JS Performance tips

Just as with Jacky’s session, I didn’t plan on making a separate post about this, but again the content was so good and I ended up taking so many notes that it also warrants its own space. To save myself from early carpal tunnel syndrome I’m going to leave this one in more of a bullet point format.

Nige

Ext JS has been getting more flexible with each release. You can do many more things with it these days than you used to be able to, but there has been a performance cost associated with that. In many cases this performance degradation is down to the way the framework is being used, as opposed to a fundamental problem with the framework itself.

There’s a whole bunch of things that you can do to dramatically speed up the performance of an app you’re not happy with, and Nige “Animal” White took us through them this morning. Here’s what I was able to write down in time:

Slow things

Nige identified three of the top causes of sluggish apps, which we’ll go through one by one:

  • Network latency
  • JS execution
  • Layout activity

Network latency:

  • Bad ux – got to stare at blank screen for a while
  • Use Sencha Command to build the app – single file, minimized
  • 4810ms vs 352ms = dynamic loading vs built

JavaScript execution:

  • Avoid slow JS engines (he says with a wry smile)
  • Optimize repeated code – for loops should be tight, cache variables outside
  • Ideally, don’t do any processing at render time
  • Minimize function calls
  • Lazily instantiate items
  • Use the PageAnalyzer (in the Ext JS SDK examples folder) to benchmark your applications
  • Start Chrome with –enable-benchmarking to get much more accurate timing information out of the browser

Layouts

Suspend store events when adding/removing many records. Otherwise we’re going to get a full Ext JS layout pass for each modification

 grid.store.suspendEvents();
 //do lots of updating
 grid.store.resumeEvents();
 grid.view.refresh()

Ditto on trees (they’re the same as grids)
Coalesce multiple layouts. If you’re adding/removing a bunch of Components in a single go, do it like this:

 Ext.suspendLayouts();
 //do a bunch of UI updates
 Ext.resumeLayouts(true);

Container#add accepts an array of items, which is faster than iterating over that array yourself and calling .add for each one. Avoid layout constraints where possible – in box layouts, align: ‘stretchmax’ is slow because it has to do multiple layout runs. Avoid minHeight, maxHeight, minWidth, maxWidth if possible

At startup:

  • Embed initialization data inside the HTML if possible – avoids AJAX requests
  • Configure the entire layout in one shot using that data
  • Do not make multiple Ajax requests, and build the layout in response

Use the ‘idle’ event

  • Similar to the AnimationQueue
  • Ext.globalEvents.on(‘idle’, myFunction) – called once a big layout/repaint run has finished
  • Using the idle listener sometimes preferable to setTimeout(myFunction, 1), because it’s synchronous in the same repaint cycle. The setTimeout approach means the repaint happens, then your code is called. If your code itself requires a repaint, that means you’ll have 2 repaints in setTimeout vs 1 in on.(‘idle’)

Reduce layout depth

Big problem – overnesting. People very often do this with grids:

{
    xtype: 'tabpanel',
    items: [
        {
            title: 'Results',
            items: {
                xtype: 'grid'
            }
        }
    ]
}

Better:

{
    xtype: 'tabpanel',
    items: {
        title: 'Results',
        xtype: 'grid'
    }
}

This is important because redundant components still cost CPU and memory. Everything is a Component now – panel headers, icons, etc etc. Can be constructing more Components than you realize. Much more flexible, but easy to abuse

Lazy Instantiation

New plugin at https://gist.github.com/ExtAnimal/c93148f5194f2a232464

{
    xtype: 'tabpanel',
    ptype: 'lazyitems',
    items: {
        title: 'Results',
        xtype: 'grid'
    }
}

Overall impact

On a real life large example contributed by a Sencha customer:

Bad practices: 5187ms (IE8)
Good practices: 1813ms (IE8)
1300ms vs 550ms on Chrome (same example)

Colossal impact on the Ext.suspendLayout example – 4700ms vs 100ms on Chrome

Summary

This is definitely a talk you’ll want to watch when they go online. It was absolutely brimming with content and the advice comes straight from the horse’s mouth. Nige did a great job presenting, and reminded us that performance is a shared responsibility – the framework is getting faster as time goes by, but we the developers need to do our share too to make sure it stays fast.

9 Responses to Sencha Con 2013: Ext JS Performance tips

  1. Pingback: Sencha Con 2013: Ext JS Performance tips | Java...

  2. Pingback: Sencha Con 2013 Wrapup | Ed Spencer

  3. useful post, thanks for sharing Ed. Here is a similar post which I appreciated a lot: http://www.sencha.com/blog/top-10-ext-js-development-practices-to-avoid/

  4. edspencer says:

    @phil life in the real world is great :)

    Oddly enough since leaving Sencha I’ve ended up building a framework and now a designer tool. Clearly my talents are so few that wherever I work I end up doing the same thing all over again!

  5. Daniil Veriga says:

    First of all, thank you for the article!

    I don’t get the “idle” event. On bootstrap, sometimes it fires once, sometimes twice. If, for example, focus a Button and move the mouse over that Button, the idle event fires a lot of times. I doesn’t look ‘a big layout/repaint run”… So, I don’t understand how to use the idle event. Could you, please, clarify?

  6. dongryphon says:

    The idle event fires on the tail of any event handler that gets wrapped by the framework (except mousemove). This can be used in at least a couple ways: 1) ensure UI states are synced with internal state w/o having to listen potentially many events to watch for changes; 2) defer a response from the current moment but not allow the browser to repaint (as would happen with a delay).

    In all cases, the contents of idle event handlers need to be careful not to perform too much work as their frequency can be a drain on performance.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 2,604 other followers

%d bloggers like this: