suspendLayouts・resumeLayouts
今回はExt.suspendLayouts、Ext.resumeLayoutsでレンダリングのチューニングを試してみます。
これを使うとDOMのレンダリングをまとめられます。
Ext.suspendLayoutsを呼び出すと、フレームワーク内部で持っているレイアウト中断のカウンタがインクリメントされ、
Ext.resumeLayoutsを引数無しで呼び出すと、フレームワーク内部で持っているレイアウト中断のカウンタがデクリメントされます。
このカウンタが0になると、レンダリングが実行されるという仕組みです(そういえばCOMでこんなの(参照カウンタ)あったなー、と思いました)。
Ext.resumeLayoutsにtrueを渡して呼び出すと、カウンタが強制的に0になります。
試してみる
検証のため1000個のボタンを追加してみます。
A. Ext.suspendLayouts、Ext.resumeLayoutsを使わない場合
Ext.define('Sample.view.sample.PanelController', { extend: 'Ext.app.ViewController', alias: 'controller.sample_panel', onClickBulkAddButton: function () { var me = this, view = me.getView(); console.time('normal'); for (var n = 1; n <= 1000; n++) { view.add({ xtype: 'button', text: '追加されたボタン' + n }); } console.timeEnd('normal'); } });
B. Ext.suspendLayouts、Ext.resumeLayoutsを使う場合
Ext.define('Sample.view.sample.PanelController', { extend: 'Ext.app.ViewController', alias: 'controller.sample_panel', onClickBulkAddButton: function () { var me = this, view = me.getView(); console.time('suspendAndResume'); // MEMO: Ext.suspendLayoutsとExt.resumeLayoutsで挟む Ext.suspendLayouts(); for (var n = 1; n <= 1000; n++) { view.add({ xtype: 'button', text: '追加されたボタン' + n }); } Ext.resumeLayouts(true); console.timeEnd('suspendAndResume'); } });
A.は約1.8秒, B.は約0.6秒という結果になり、Ext.suspendLayouts、Ext.resumeLayoutsを使った方が速いことがわかります。