PDA

View Full Version : [OPEN] Unneeded refresh of the grid view after store "write" event



ruslan.talpa
22 Jan 2014, 2:53 AM
If you use a grid with any editing plugin and a restful store, this is the sequence of the "events" which generates multiple dom operations, some of them very expensive and unneeded

1. you edit a record and the afterEdit function from Ext.data.AbstractStore will do this:
me.fireEvent('update', me, record, Ext.data.Model.EDIT, modifiedFieldNames)
this will trigger the view to refresh of row for that specific record (so far so good)

2. After the record is synced, the afterCommit function will do this:
this.fireEvent('update', this, record, Ext.data.Model.COMMIT, modifiedFieldNames);
this will again trigger the view to refresh of row for that specific record (this is also ok since it's possible the api server changed some of the values)

3 Next comes a sequence of events in onProxyWrite in Ext.data.AbstractStore:
if (success) {
me.fireEvent('write', me, operation);
me.fireEvent('datachanged', me);
me.fireEvent('refresh', me);
}
At this point the grid view is in sync with store but the refresh event from the store triggers a complete refresh of the grid view, event if we only updated 1 record, event if the step 2 actually updated all the dom nodes that needed updating for that record.

I think this can be optimized.
My temporary fix for this is to listen for the 'write' event on the store and set the blockRefresh flag to true in order to prevent the useless rerendering of the entire grid.

ruslan.talpa
23 Jan 2014, 5:12 AM
If you have encountered the problem above and in your grid you also use the grouping feature, take a look at this bug also, http://www.sencha.com/forum/showthread.php?280286-Ext.grid.feature.GroupStore-should-propagate-idchanged-event&p=1024690 you need to add this fix too

Gary Schlosberg
24 Jan 2014, 10:22 AM
Thanks for the report and workaround. Can you please post a runnable test case which reproduces this issue?

ruslan.talpa
26 Jan 2014, 11:27 PM
1. Download a fresh copy of ext (i tested this in 4.2.1gpl just now but it's the same in 4.2.2 comercial)
2. Place it in your web root
3. Open the "restful" exemple and edit the restful.js as follows:

after line 137 (the last line in onReady function) add the following:


Ext.util.Observable.capture(store, function(ev){console.log('store', ev);});
Ext.util.Observable.capture(grid.getView(), function(ev){console.log('view', ev);});


4. Open restfull.html in the browser and double click one of the lines to enter edit mode (at this poin the console is already full of log lines so it's a good idea to clear it)
5. Focus back on the edit input and hit enter (just so that you do not generate any other mouse events on the view)
6. The console log output will be:


store beforesync restful.js:139
store update restful.js:139
view itemupdate restful.js:140
view rowfocus restful.js:140
store update restful.js:139
view itemupdate restful.js:140
store write restful.js:139
store datachanged restful.js:139
store refresh restful.js:139
view beforerefresh restful.js:140
view refresh restful.js:140
view rowfocus restful.js:140


7. Notice the view generates 2 itemupdate events and in the end 1 refresh (which is unneeded)

ruslan.talpa
27 Jan 2014, 6:15 AM
One observation:
The fix i described (listen to the "write" event on the store and set the blockRefresh flag true on the view) works quite good with one little exception, the cells remain visually marked as "dirty" although that is not true (teh record and the dom is are in sync).
That is because the Ext.tree.View.updateColumns function does not render the entire dom for the row (in which case there would be no problem but would be quite expensive), but updates the content of the already existing dom nodes here


Ext.fly(oldCell).syncContent(newCell);


probably after that line, it would be necessary to remove the "dirtyCls" from all the nodes if the record that is being synced to the dom is not dirty