PDA

View Full Version : Extjs Grid is causing IE8 script timeout & alert for stop script.



sagi.kiran
11 Jul 2012, 4:20 AM
Hi,

ISSUE : I am having Extjs Grid panel (Extjs 4.0.7) with 8 columns.
In that 1 column does have hyperlink with tool-tip & 1 column have two hyperlinks.
I am trying to load more than 4000 records on page.
While rendering grid on IE8 - I am getting alerts for stop script (might cause of script timeout or some other way).

NOTE:
- I am getting records in my controller / action bean within 10 seconds.
- I am able to display all records ( > 4000 rows) on Mozilla firefox within 30 seconds. (Mozilla firefox occupies 100% CPU usage for 10 seconds)
- I can not use pagination because of certain requirements.

Please find attachment of Extjs Grid display ( IN Mozilla) with this mail.37054

My grid definition is given below:
Ext
.define(
'qnum.view.familyblocks.CurrentAllocationByNumberGrid',
{
extend : 'Ext.grid.Panel',
qid : 'currentAllocationByNumberGrid',
alias : 'widget.currentallocationbynumbergrid',

store : 'familyblocks.CurrentAllocationByNumberStore',
initComponent : function() {
this.columns = [
{

text : 'Id',
dataIndex : 'familyBlockId',

hidden : true

},
{

text : 'Block',
dataIndex : 'range',
sortable : true,
flex : 1

},
{

text : 'Product Lines',
flex : 1,
dataIndex : 'productLines',
sortable : true,
renderer : function ftcheck(value,
metaData, record, rowIndex,
colIndex, store) {
var currentAllocationbynumberGrid = Ext.ComponentQuery
.query('#content-panel panel[qid=currentAllocationByNumberGrid]')[0];
var rec = currentAllocationbynumberGrid.store
.getAt(rowIndex);
var productLineDesc = rec
.get('productLineDesc');

metaData.tdAttr = 'data-qtip="'
+ productLineDesc + '"';

return '<a href="javascript:void(0)">'
+ value + '</a>';
}

},
{

text : 'Product Lines',
dataIndex : 'productLineDesc',

hidden : true

},
{

text : 'Total',
dataIndex : 'totalNumbers',
flex : 1

},
{

text : 'Reserved',
dataIndex : 'reservedNumber',
flex : 1

},
{

text : 'Used Reserved',
dataIndex : 'usedReservedNumber',
flex : 1

},
{

text : 'In Use (in Agile)',
dataIndex : 'usedAgileNumber',
flex : 1

},
{

text : 'Available',
dataIndex : 'availableNumbers',
flex : 1

},
{

text : 'Action',
flex : 1,
dataIndex : 'actionAvailable',

renderer : function(value, metaData,
record, rowIdx, colIdx, store) {
var testValue = value;
var currentAllocationbynumberGrid = Ext.ComponentQuery
.query('#content-panel panel[qid=currentAllocationByNumberGrid]')[0];
var recCheck = currentAllocationbynumberGrid.store
.getAt(rowIdx);
var availableNumbers = recCheck
.get('availableNumbers');
var productLineValue = recCheck
.get('productLines');
if (testValue == 'true'
&& productLineValue != 0
&& productLineValue != ''
&& Number(availableNumbers) > 0) {

return '<table cellpadding="2" cellspacing="2"> <tr><td><a style="font-size:10px;cursor: pointer; cursor: hand ;text-decoration:underline;" onclick="Util.reallocateViewNumber('
+ rowIdx
+ ',\''
+ store.storeId
+ '\');" >Reallocate </a></td><td><a style="font-size:10px;margin-left:2px;cursor: pointer; cursor: hand ;text-decoration:underline;" onclick="Util.deallocateViewNumber('
+ rowIdx
+ ',\''
+ store.storeId
+ '\');"> Deallocate</a></td></tr></table>';
} else {

return 'No Available Numbers';
}
}

} ];
this.qtipTpl = new Ext.XTemplate('<tpl for=".">',
'<div></div>', '</tpl>');
this.callParent(arguments);
}

});

I am not sure what is wrong with above Extjs Grid code. If code optimization required in above implementation then please provide suggestions for the same too.

Tim Toady
11 Jul 2012, 5:55 AM
4000 is too many records without some sort of paging/buffering. See the below example.

http://docs.sencha.com/ext-js/4-0/#!/example/grid/buffer-grid.html

sagi.kiran
11 Jul 2012, 7:52 AM
Hi Tim,

Thanks for your reply.
I have explored buffered grid option but only issue I am facing is sorting on columns with Buffered grid.
If you observe it applies sort to only 50 recrods (or whatever pagesize is defined). I would require sort on entire rows.
Any suggestions?

Tim Toady
11 Jul 2012, 8:31 AM
Someone can correct me if I am wrong, but I don't think sorting is supported with a simple buffered grid (unless you roll it yourself or find a post from someone who has or hack it to sort remotely). If sorting is not a requirement, disabling it would be your best option. Otherwise you are going to have to page and sort remotely. If the no paging requirement is just a visual thing about the pagingbar, then infinite scrolling is the way to go. My understanding is that it is a little painful in 4.07 though. I have only done it in 4.1 myself.

http://docs.sencha.com/ext-js/4-0/#!/example/grid/infinite-scroll.html

dbrin
11 Jul 2012, 9:23 AM
Hi Kiran,
I have faced similar situation before where rendering a large list is too taxing on the browser.
Here are my thoughts and suggestions on this:

1. Displaying over 100 (my personal preference is about 50) rows of data at a time for users is not practical from user experience point of view. Scrolling through pages of records is not very useful. Most people can not take in this much data in any meaningful ways. Instead users would be looking for specific row or a subset, maybe even some sort of summary. So offering a search/filter/sort options should be offered first. (keep in mind that search is usually preferred over sort)

2. When requirements insist on displaying entirety of the database all at once - fight it. I would go as far as saying it's your job as a programmer and UI developer to push back on this type of requirement, and always offer alternatives.

3. When you loose the hard fought battle in point 2, not all is lost yet. Your options with ExtJS are as follows: Paging, Buffered grid. In both cases you are only showing subset of the data and that means sorting/filtering must be performed server side (see API docs for remote sort options). Buffered grid is a great alternative when users hate the idea of paging, but don't mind "scrolling". You could get creative and split up your data into subsets in other ways (like tabs, or some other UI presentation that direct users to select a smaller set of data).

4. Granted IE performance is not great, but 30 second wait time even on FF is not a good user experience either, you should not make users wait 30 seconds to load data. Which should throw a red flag that perhaps this is not a good approach.

5. Code optimization: looking through your code there are things you can improve from performance standpoint.
a) Column Renderers: If you think about it column renderers will run for every cell/data point. That means a piece of code that perform a somewhat benign operation run 4000 times will have performance impact. A more expensive operation will have even greater implication. I noticed that you have several renderers that perform ComponentQuery to find the same object over and over again. This is a great opportunity to take out this operation from a loop and cache the reference to the object outside the renderer function. Furthermore you are looking up a record by index in another store to pickup a description - perhaps it would be better to bring in that description value inline with the data being rendered?
b) XTemplates: I noticed that one of the renderes constructs a table by concatenating a large number of strings together. By itself it's not a big deal, however when you multiply 'not a big deal' 4000 times you get less than optimal performance. My suggestion is to create an XTemplate that would compile your table template and run against a data record to populate (there is a template column type just for that purpose). I would guess this would be better from performance stand point.
To read more about performance optimization there is a nice post: here (http://www.sencha.com/blog/ext-js-4-1-performance)

scottmartin
11 Jul 2012, 10:25 AM
Good points .. concentrate on what the user can see, not how many records can be loaded.

In the old days, I used to load all the data in a Win32 grid. I web based apps, I moved everyone over a filtered grid displaying on the required data. I have yet to hear any complaints once they understood how much more useful it was.

Scott.