There are some standard optimizations that need to be set, which will let you speed up the grouping engine and correct such performance problems, when many rows are present. Please try the following optimization settings for your GridGroupingControl.
void OptimizeGridSettings(GridGroupingControl grid)
grid.CounterLogic = EngineCounters.YAmount;
grid.AllowedOptimizations = EngineOptimizations.DisableCounters | EngineOptimizations.RecordsAsDisplayElements;
grid.UseDefaultsForFasterDrawing = true; // GDI interop drawing, FirstNRecords Summaries
grid.InvalidateAllWhenListChanged = false; // only paint modified cells
grid.InsertRemoveBehavior = GridListChangedInsertRemoveBehavior.ScrollWithImmediateUpdate;
grid.UpdateDisplayFrequency = 50; // update every number of ms (speciy 0 if Update should occur manually, 1 if immediately)
//grid.TableControl.EnableDoubleBufferSurface(); // reduce flickering
// Instruct grouping control not to access datasource through
// CurrencyManager API and instead access list diretly. When set to
// false you wil howver loose support for built-in CurrencyManager
grid.BindToCurrencyManager = false;
Also refer to the below forum thread for EngineOptimization and counter.http://www.syncfusion.com/support/forums/message.aspx?MessageID=26047
Take a look at the performance based samples in GridGroupingControl from the shipped browser samples
Also you could try GridGroupingGrid.Engine.AllowCacheStyles and Enable this flag if you want GridRecordRow and GridCaptionRow elements to keep a cache with style information for individual cells and reduce the number of QueryCellStyleInfo calls being raised for these cells.
Other things you could look at is overriding Table.ShouldCacheRecordData.
Here is how the base class version looks like:
/// Method is called when the table tries to determine whether a record''''''''s underlying data row can be cached
/// within objects.
/// True if record''''''''s underlying data row can be cached
/// within objects; False otherwise.
protected virtual bool ShouldCacheRecordData() // called when SourceList is changed
return ((SourceList) is IGroupingList) && ((IGroupingList) SourceList).AllowItemReference || SourceList is System.Data.DataView;
Another setting is Engine.AllowSwapDataViewWithDataTableList. It Gets / sets if the engine can wrap access to a DataTable with a which provides optimized access to the rows of the datatable. Engine will access a DataTable through this wrapper class instead of accessing records through the DataTable.DefaultView to increase performance when adding, removing, and changing records when Engine.AllowSwapDataViewWithDataTableList is enabled. Default is False. --- but that should normally not affect scrolling.