View Full Version : [DEFER-1255] updating rows in ListView > 2x more CPU than necessary due to reflow

4 Sep 2010, 1:34 PM
The issue is that updating a row calls ListView.verifyInternalSize(), which in turn calls ListView.onResize(), which updates the style.width of the innerBody and innerHd. When I walked through this in firebug in Firefox 3.6.7, most of the time the new width was the same as the old width -- but poking the style object triggered a reflow anyway.

Here's the profile of code that periodically updates three records in a store that's being shown in a ListView. Every time record.endEdit() is called, ListView.onResize() gets called:

Profile (5685.886 ms, 366,662 calls)
onResize 674 28.24% 1605.413ms 1617.527ms 2.4ms 1.846ms 14.063ms ext-all-debug.js (line 27568)
overwrite 674 14.15% 804.384ms 1871.673ms 2.777ms 1.409ms 36.757ms ext-all-debug.js (line 450)
replaceElement 650 12.08% 687.102ms 1026.798ms 1.58ms 1.367ms 10.908ms ext-all-debug.js (line 6314)
encodeArray 698 4.39% 249.817ms 458.082ms 0.656ms 0.205ms 2.32ms ext-all-debug.js (line 8341)
(?) 650 2.97% 169.074ms 300.023ms 0.462ms 0.341ms 3.338ms ext-base-debug.js (line 332)
fireEvent 6429 1.96% 111.428ms 5595.825ms 0.87ms 0.007ms 199.243ms ext-all-debug.js (line 1455)
Here's a profile of the same test being made where ListView.onResize() has been tweaked to not change style.width if the new value is the same as the old value. Due to timing issues in the test, the number profiled calls in the first test is about 10% higher, so you'd expect this second test to be a little faster -- but instead, it's nearly three times faster :

Profile (1962.586ms, 165337 calls)
onResize 168 13.37% 262.33ms 273.554ms 1.628ms 1.277ms 3.517ms ext-all-debug.js (line 27568)
overwrite 168 9.8% 192.371ms 468.434ms 2.788ms 1.477ms 9.124ms ext-all-debug.js (line 450)
replaceElement 144 7.46% 146.499ms 231.605ms 1.608ms 1.473ms 2.711ms ext-all-debug.js (line 6314)
fireEvent 5814 6.68% 131.185ms 1336.803ms 0.23ms 0.008ms 39.446ms ext-all-debug.js (line 1455)
asyncRequest 42 3.77% 73.895ms 748.591ms 17.824ms 11.05ms 28.781ms ext-base-debug.js (line 1741)

I don't know whether poking style.width causes unconditional reflow in other browsers, but according to this profile, avoiding it can make a significant improvement in Firefox.

Disclaimer: I'm fairly new to Javascript and Ext, and Ext's bug tracker seems to be for paying customers only. So I don't know whether or not this is already a known issue or whether there's a workaround that I can use in client code.

There might be some similar wins to be had in GridView.updateAllColumnWidths() and GroupingView.updateGroupWidths(), but I'll leave that to someone who knows more about this.

Jamie Avins
7 Sep 2010, 9:51 AM
Some good analysis, we are doing some major overhaul of this for 4.x and want to keep this open to make sure it's factored in. I'd suspect Webkit is also effected the same way, but it's hard to notice since it's much faster.