View Full Version : Containers with CSS-driven layouts: how to make Ext get out of the way?

31 Jan 2013, 5:01 AM
I have an ExtJS application with highly customized appearance that is mostly defined by CSS. I have multiple forms throughout the app that are dynamically configured when they load records.
Without going into much detail, the structure of forms is quite typical:


As I noticed, I havethe appearance as well as dimensions for most elements (form fields and other child items) completely defined in CSS. This means:

many elements have fixed sizes and I am ok about that. I have custom layout logic that places forms around the viewport area but forms themselves are not fluid: their widths are fixed and their heights are just naturally managed by the browser
I only care about modern browsers. IE<8 is not supported. Even IE8 has basic support.
The big question is: what is the maximum I can do to make ExtJS layout system get out of the way? Basically what I want to preserve is:

component hierarchy (so child items have proper ownerCt and are present in the items collection of their parents) so that ComponentQuery, component event bubbling and some other things work properly
containers rendering their children (just rendering! nothing beyond that)
In fact I already achieved the desired appearance and behavior - form panels and their contents look as they need to (styled via CSS, including sizing when needed), everything gets loaded and rendered properly. The only thing that bothers me is that every time I (re)load a form, Ext's layout system performs a lot of work that I don't need or care about, hugely decreasing performance of my app.

Note that I recently upgraded from 4.0 to 4.1 and had really high hopes to see increased layout performance. I was really excited that now there's a re-enterable method Ext.AbstractComponent.suspendLayouts() (http://docs.sencha.com/ext-js/4-1/#!/api/Ext.AbstractComponent-method-suspendLayouts) that took place of the pathetic this.suspendLayout = true; which kept being overridden in Ext's base methods when I was doing complex operations on form load. But even after some tinkering around and finally making all the Layout run failed console logs go away, I didn't win as much milliseconds (form load time) as I had expected.

What I've done so far:

Set layout: 'auto' for my form panels, fieldsets and some other complex components.
The docs say:
The AutoLayout is the default layout manager delegated by Ext.container.Container to render any child Components when no layout is configured into a Container. AutoLayout provides only a passthrough of any layout calls to any child containers.

However, for some reason there's still a ton of things happening besides just rendering child items!
Set shrinkWrap: true; on all field components to eliminate the "Layout run failed" messages.

by the way I didn't really get whether this property increases or decreases performance

Setting componentLayout: 'auto'; on the form panel now breaks things so I commented it out
In 4.0, the following override on field items and other form children noticably improved layout performance and prevented Ext's layout setting some unwanted inline styles:
getBodyNaturalWidth: function (){ return undefined; }
However, the method isn't used in 4.1 anymore.
Are there any other useful tricks to minimize Ext layouts' impact? Other magic properties or overrides? Performance is not the only concern, the layouts often override the styles set in my CSS. Is there a way to achieve a true auto layout that wouldn't try to determine dimensions of components and inject inline styles like width/height/border? In the rare cases I need this I can do it myself via custom code but I want to really separate component logic from their appearance and I think it makes a lot of sense (the data definition and data presentation topic). The only reference to styles I want in my .js files is by adding CSS classes to components.

Now I understand that Ext's layout system is a huge monster and, while defined separately in the codebase, it still appears to be tightly weaved into the component system and it's probably impossible to completely achieve what I'm trying to do without rewriting the whole framework but any kind input is highly appreciated.

I noticed that there have been tangential discussions before:

Control styles totally in external css file? (http://www.sencha.com/forum/showthread.php?250356)
Layout structure question (http://www.sencha.com/forum/showthread.php?229527)
HTML-focused DOM Layout for auto-height web applications (Ext 4.1) (http://www.sencha.com/forum/showthread.php?185214-HTML-focused-DOM-Layout-for-auto-height-web-applications-(Ext-4.1))
But there was never any helpful advice besides "let the framework do its job". I guess I wouldn't mind and would work around inline style overrides but I don't want my forms to load for 30-40ms where it shouldn't take more than 10ms, and letting the browser manage the layout is always supposed to speed things up, not slow them down. I'm pretty confident I'm not the only one with such issue, let's share our experience.

Great thanks to all in advance!

4 Feb 2013, 9:09 AM
If you don't specify a layout on the container, it will use auto layout which doesn't do a whole lot. You should be able to do use CSS to lay things out for the most part.

5 Feb 2013, 3:22 AM
I am specifying layout: 'auto' on components. However a lot of stuff is still happening.

6 Feb 2013, 1:02 AM
One of the things I am still struggling with is preventing Ext from setting width and height and other CSS properties to Panel's body element, this sometimes overrides my styles.

The manageHeight (http://docs.sencha.com/ext-js/4-1/#!/api/Ext.panel.Panel-cfg-manageHeight) property looks like the one I need:

When true, the dock component layout writes height information to the panel's DOM elements based on its shrink wrap height calculation. This ensures that the browser respects the calculated height. When false, the dock component layout will not write heights on the panel or its body element. In some simple layout cases, not writing the heights to the DOM may be desired because this allows the browser to respond to direct DOM manipulations (like animations).

I set manageHeight to false, however, the body element still gets the following styles:

width: 320px;
margin-left: 0px;
margin-top: 0px;
height: 380px;


The only effect that manageHeight seems to have is turning the left and top inline styles into margin-left and margin-top. Is that the intended behavior? Why doesn't it perform as described in the docs?

P.S. The componentLayout on my Panels is set to dock and I can't set it to auto since it breaks things.