-
6 Nov 2011 8:25 AM #11
Batching
Batching
Try to batch changes that cause re-rendering so that the rendering only happens once at the end.
For example, changing a field value in a record will immediately update the grid. If you want to update several fields it's more efficient to batch them:
The more fields you change the more noticeable the effect will be.Code:record.beginEdit(); record.set('name', 'Tom'); record.set('age', 17); record.set('member', true); record.endEdit();
Another example is adding components to a container. The container will recalculate its layout every time add() is called. Passing multiple items to the same add() call will be much more efficient.
In cases where no other batching mechanism exists it can help to suspend layouts temporarily:Code:// slow container.add(panel); container.add(button); container.add(grid); // fast container.add(panel, button, grid); // using an array, also fast container.add([panel, button, grid]);
Code:container.suspendLayout = true; doSomethingThatCausesLotsOfLayoutChanges(); container.suspendLayout = false; container.doLayout();
-
6 Nov 2011 8:28 PM #12
Re: Batching
Re: Batching
In 4.x, you can use the multi-value form of set which has a built-in begin/endEdit mechanism:
New to 4.1, layouts are suspended via method call to avoid problems that we encountered via nested suspend/resume logic (the boolean suspendLayout is still respected). This can be done on a single component:PHP Code:record.set({
name: 'Tom',
age: 17,
member: true
});
Or if you are manipulating multiple components, there is a global suspend mechanism:PHP Code:container.suspendLayouts(); // plural "layouts"
...
container.resumeLayouts(true); // true=run layout if 0 suspend count
PHP Code:Ext.suspendLayouts();
...
Ext.resumeLayouts(true); // true=run layouts if 0 suspend count
Don Griffin
Ext JS Development Team Lead
Check the docs. Learn how to (properly) report a framework issue and a Sencha Cmd issue
"Use the source, Luke!"
-
7 Nov 2011 8:01 PM #13
deferredRender
deferredRender
To expand on Mitchell's earlier comment...
When using a card layout or tab panel, be careful to consider the deferredRender option. When set to true it will cause the hidden cards/tabs to be lazily rendered. Rendering will only occur when the hidden items are first shown. When set to false, all cards/tabs will be rendered at the same time, as part of the rendering of the container.
Usually it is better to defer rendering as it helps to break the rendering process up into smaller chunks that won't cause a noticeable delay to the user. However, rendering all the cards/tabs up front can help to improve responsiveness of the UI when the hidden cards/tabs are first shown.
-
9 Nov 2011 12:58 PM #14
When using a grid, if you have a large data set, use buffered rendering.
This means that the Store keeps a "prefetch" buffer containing a page of Records which is used when possible to load the Store.
As long as the data set is less than maybe 100,000 rows, it's probably best to keep all the data in the client in this prefetch buffer.
It's the rendering of a large HTML table that kills performance. That's just a fact of the HTML table algorithms. Just holding all the data should not cause problems.
What we can do is do "just in time" rendering of the rows in the table as we scroll.
To do this, first load the prefetch buffer with all the data. And when that is done, you can then load the Store's main data cache from the prefetch:
Code:myStore = ...{ ..., buffered: true, // Tells grid to use a Paging scroll manager to scroll and refresh the table automagically purgePageCount: 0, // never remove pages from the prefetch buffer ... }
What that does is prefetches what is hopefully the whole data set. Then the callback loads the Store's main cache (the cache that is mapped to a <table> within the GridPanel) with the first 50 rows.Code:myStore.prefetch({ start: 0, limit: 999999, callback: function() { myStore.load(0, 49); } });
So we only get a small 50 row table.
As it scrolls nearly out of view, it is refreshed.
This technique works OK in 4.0.x, but it has been really overhauled in 4.1.0 and will be extremely fast and smooth.
The buffer-grid example in the grid directory illustrates this technique.
Be aware that it seems that a large number of columns has an effect on the performance of HTML <table> elements too, so avoid columns which do not really need to be present.Search the forum: http://www.google.com/coop/cse?cx=01...%3Az7of1ufqccu
Read the docs too: http://extjs.com/deploy/dev/docs/
Scope: http://extjs.com/forum/showthread.ph...642#post257642
-
9 Nov 2011 9:43 PM #15
Grid store size
Grid store size
Obviously 100K rows may sound like a lot, but the amount of memory you can utilize in the browser is quite surprising. The ideal number may take some experimentation and will depend on the number of fields in your model as well, but you would be amazed at how much speed you can gain by using more memory.
Don Griffin
Ext JS Development Team Lead
Check the docs. Learn how to (properly) report a framework issue and a Sencha Cmd issue
"Use the source, Luke!"
-
12 Nov 2011 6:34 AM #16
Great thread and great tips. I think a lot of us needed this. Regarding Animal's buffered rendering suggestions, I am getting an incorrect behaviour, on both 4.0.7 and 4.1-pr1. I do not know if I am doing something wrong or if it is a bug. If someone has a clue either way, please let me know
I am loading a buffered store in FF 7.0.1 and monitoring the XHR calls through firebug. The buffer is correctly loaded through the proxy. But when I use myStore.load(0, 49) the whole store is loaded again via the proxy and the full table is rendered, which kind of defeats the purpose.
my test setup (I simplified it as much as I could think of)
the firebug output:Code:Ext.define('edm.model.Doc', { extend: 'Ext.data.Model', fields: [ {name: 'id', type: 'int'} ], proxy: { type: 'rest', url: '/docs', reader: { type: 'json', root: "data", defaultRootId: 'root' } }, constructor: function() { this.callParent(arguments); }, }); Ext.define('edm.store.Docs', { extend: 'Ext.data.Store', model: 'edm.model.Doc', buffered: true, purgePageCount: 0, clearOnPageLoad: false }); myStore = Ext.create('edm.store.Docs'); myStore.prefetch({ start: 0, limit: 999999, callback: function() { console.log('prefetched') myStore.load(0, 49); console.log('loaded') } });
I later use the console to check the store is correctly loaded:Code:GET http:/127.0.0.1/docs?_dc=1321107103812&start=0&limit=999999 prefetched GET http:/127.0.0.1/docs?_dc=1321107104216&page=1&start=0&limit=25 loaded
Update: I also tried to use myStore.load({start:0, limit: 50}); but the proxy is still accessed instead of the buffer.Code:>>console.log(myStore.first().get('id')) 1
Update: I got it to work by replacing store.load by store.guaranteeRange and adding a pageSize parameter to the store:
the firebug output is now:Code:Ext.define('edm.model.Doc', { extend: 'Ext.data.Model', fields: [ {name: 'id', type: 'int'} ], proxy: { type: 'rest', url: '/docs', reader: { type: 'json', root: "data", defaultRootId: 'root' } }, constructor: function() { this.callParent(arguments); }, }); Ext.define('edm.store.Docs', { extend: 'Ext.data.Store', model: 'edm.model.Doc', pageSize: 50, buffered: true, purgePageCount: 0, clearOnPageLoad: false }); myStore = Ext.create('edm.store.Docs'); myStore.prefetch({ start: 0, limit: 999999, callback: function() { console.log('prefetched') myStore.guaranteeRange(0, 49); console.log('loaded') } });
Code:GET http:/127.0.0.1/docs?_dc=1321107103812&start=0&limit=999999 prefetched loaded
Last edited by _matias_; 16 Nov 2011 at 12:37 PM. Reason: Fixed
-
18 Nov 2011 12:53 PM #17
Did I kill the thread ?
-
18 Nov 2011 12:54 PM #18Sencha - Senior Forum Manager
- Join Date
- Mar 2007
- Location
- St. Louis, MO
- Posts
- 33,582
- Vote Rating
- 433
Mitchell Simoens @SenchaMitch
Sencha Inc, Senior Forum Manager
________________
http://www.JSONPLint.com - Source to lint your JSONP!
Check out my GitHub, lots of nice things for Ext JS 4 and Sencha Touch 2
https://github.com/mitchellsimoens
Think my support is good? Get more personalized support via a support subscription. https://www.sencha.com/store/
Need more help with your app? Hire Sencha Services services@sencha.com
Want to learn Sencha Touch 2? Check out Sencha Touch in Action that is almost in print!
When posting code, please use BBCode's CODE tags.
-
20 Feb 2012 3:34 PM #19Sencha Premium Member
- Join Date
- Feb 2009
- Location
- Amsterdam, The Netherlands
- Posts
- 217
- Vote Rating
- 2
Consider using Base64 if there is no need to support older versions of IE:
http://code.google.com/p/wro4j/wiki/...DataUriSupport
-
21 Feb 2012 1:06 AM #20


Reply With Quote