View Full Version : Diagnosing layout failures

31 Oct 2011, 10:50 AM
(Update 7-March-2012: the new Page Analyzer described in the blog post (http://www.sencha.com/blog/optimizing-ext-js-4-1-based-applications) has better visualization of layout failures -- removing Sticky on this thread)

First off we want to thank everyone who has downloaded 4.1PR and especially those who have reported their findings. Your input is greatly appreciated.

To assist in this process, we have created a layout "diagnostic layer" that can be used to help isolate the root cause of layout failures. It is enabled by adding a couple script tags after Ext. The two files are not included in normal builds and so cannot be loaded by the dynamic loader (at present). They are located in the src/diag/layout folder in the downloaded zip:

<script src="ext-all-debug.js"></script>
<script src="src/diag/layout/ContextItem.js"></script>
<script src="src/diag/layout/Context.js"></script>

You will need a debug console to view the results.

For the vast majority of users, these diagnostics will simply indicate that a layout failure has occurred. Beyond that failure, you can expect problems including JS errors. If a layout failure has occurred, then, it is best to focus only on that issue and not on any subsequent behaviors.

For those that want to write custom layouts, the details from the diagnostic can help identify where results stalled but it will take some time and practice to sort through all the data provided.

A good run will generate a report that says "SUCCESS" while a failed run says "FAILURE". In a failed run, the layout tree is written to the console with "++" indicating completed layouts and "--" indicating unfinished layouts. Something like this (where I have highlighted the missing values):

-- viewport<absolute>
triggeredBy: count=3
ext-gen1003.containerChildrenDone:dom () dirty: false, setBy: ?
ext-gen1003.height (954) dirty: false, setBy: viewport<autocomponent>
ext-gen1003.width (1670) dirty: false, setBy: viewport<autocomponent>
--testA<dock> - ownerCt: viewport
triggeredBy: count=3
testA.height (110) dirty: false, setBy: testA<dock>
testA.width (250) dirty: false, setBy: testA<dock>
testA_header.height () dirty: false, setBy: ?
--testA_header<body> - ownerCt: testA
triggeredBy: count=2
testA_header.contentHeight () dirty: false, setBy: ?
testA_header.width (250) dirty: false, setBy: testA<dock>
--testA_header<hbox> - ownerCt: testA
triggeredBy: count=2
testA_header-body.width (239) dirty: false, setBy: testA_header<body>
tool-1015.width (15) dirty: false, setBy: tool-1015<autocomponent>
--testA<autocontainer> - ownerCt: viewport
triggeredBy: count=3
testA-body.height () dirty: false, setBy: testA<dock>
testA-body.width (250) dirty: false, setBy: testA<dock>
testA.containerChildrenDone:dom (true) dirty: false, setBy: ?

In the above, I deliberately forced the hbox layout to not publish contentHeight (a value published by container layouts when autoHeight) which caused the body layout to stall since it needed that value (it is triggeredBy it) in order to calculate the header's height. This in turn caused the dock layout to stall because it needed the height to dock the header component. Finally, the viewport was waiting for all of its child items to complete before it could perform its final steps.

Hopefully this tool will be of some assistance externally. It has been of great value to us internally as we have been working out the interactions between the many layout managers in Ext JS.

1 Nov 2011, 10:12 AM
I'll definitely be looking at this, as I have a custom field layout that I use extensively.

1 Nov 2011, 12:30 PM
There is a lot of documentation on the new layout system in layout/Context. It is largely up to date, but needs review since it was written over a month ago.

Feel free to ask questions about custom layouts of course.

I have it on my TODO list to see about simplifying the guts of calculateBodyNaturalWidth and just measure the outer el. There were issues with this in the past, but I think they are largely historical now or will be when I finish up the rest of the "autoWidth" magic... er, logic :)

26 Dec 2011, 12:45 PM
I'll definitely be looking at this, as I have a custom field layout that I use extensively.


The field layouts have changed dramatically since PR1. I hope the docs on Base and Labelable explain the new "decorator" tpl's... they could be enough to avoid an override of fieldSubTpl and might be enough to avoid writing a custom layout altogether.

I am very curious to hear your mileage on the new (low-calc) layouts for field.

3 Feb 2012, 2:58 AM
Some panel layout is bad at the first showing. After switched from other tabs, it become normal. Why?
For example:
1st show:

2nd show:

3 Feb 2012, 9:51 AM
@andasoft. Which version are you using? Are you able to provide a test case? Does this happen consistently across all browsers? Did this work against a previous version and if so which version was it?

3 Feb 2012, 10:44 PM
The problem version is 4.1 beta2, it works well in version 4.0.7. Its performance is the same in Chrome and Firefox.


<html><head> <title></title>
<link rel="stylesheet" type="text/css" href="extjs/resources/css/ext-all.css"> <script type="text/javascript" src="extjs/ext-all-debug.js"></script> <script type="text/javascript">Ext.require([ 'Ext.grid.*', 'Ext.form.*', 'Ext.layout.*']); Ext.onReady(function() {
var basicInfoForm = Ext.widget('form', { frame:true, border:false, renderTo:Ext.getBody(), layout:'column', fieldDefaults: { labelWidth:80, labelAlign:'right' }, defaults:{columnWidth:.25},
items:[ { xtype:'textfield', name: 'fmsBizCode', fieldLabel: '????', readOnly: true }, { xtype:'textfield', name: 'devCode', fieldLabel: '????', readOnly: true }, { fieldLabel:'???', xtype:'textfield', labelWidth:80, name:'contactName' },
{ fieldLabel:'????', xtype:'textfield', labelWidth:80, name:'phoneNumber' }, { fieldLabel:'????', xtype:'textfield', allowBlank:false, labelWidth:80, columnWidth:.5, name:'location' }, { xtype:'numberfield', allowBlank:false, name: 'splitPcs', minValue:0, fieldLabel: '?????', labelWidth:80 }, { xtype:'numberfield', allowBlank:false, name: 'boxes', minValue:0, fieldLabel: '???', labelWidth:80 }, { xtype:'numberfield', allowBlank:false, name: 'labels', minValue:0, fieldLabel: '???', labelWidth:80 }, { xtype:'datefield', fieldLabel: '??????', allowBlank:false, name: 'actualShipmentDate', format: 'Y-m-d', labelWidth:80 }, { xtype:'timefield', fieldLabel: '??????', allowBlank:false, name: 'actualShipmentTime', format: 'H:i:s', labelWidth:80 }, { xtype:'textfield', fieldLabel: '??', name: 'memo', columnWidth:.75, labelWidth:80 }, { xtype:'numberfield', fieldLabel: '???', name: 'pltsNumber', labelWidth:80 } ], tbar:[ { xtype:'button', text:'??', iconCls:'silk-save', itemId:'saveBasicInfoBtn' }, '-', { text: '????', iconCls: 'silk-accept', disabled:true, itemId:'closeCaseBtn' }, { itemId:'forceToCloseCheckbox', disabled:true, boxLabel: '<font color="red">??????</font>', xtype: 'checkbox' }, '-', { text:'??', disabled:true, iconCls:'silk-door', itemId:'closeBtn' }, '-', { itemId:'discardBtn', text : '??', iconCls: 'silk-discard' }, '-', { xtype:'displayfield', fieldLabel:'??', margin:'5 5 5 5', labelAlign:'right', labelWidth:30, name:'displayStatus', value:'???' }, '-', { text:'?????', iconCls:'silk-book-go', itemId:'transferBtn' } ] });

3 Feb 2012, 10:48 PM
the zip file.

16 Apr 2013, 1:39 PM
Am I reading this right? Is the root cause for the layout failure the deepest node in my diagnoses tree?

16 Apr 2013, 10:53 PM
Am I reading this right? Is the root cause for the layout failure the deepest node in my diagnoses tree?

If you post the raw JSON data I can look at it and see, but the tree displays Red icons for failed layouts and Orange icons for containers with failed child layouts. The key to understanding the root cause is the Triggers which represent the data flow between the layouts. That takes some time to see the patterns there but what you are looking for is some unknown variable (a trigger) that *should* be knowable at the moment of the failure.

Often times the failure comes down to a situation where the layout definition is somehow contradictory and no solution can be found, but it can also be a bug. On that front, there is a bug fix in recent nightly builds to do with constraint handling.