iSeller Commerce
iSeller POS Retail
iSeller POS F&B
iSeller POS Express
Crosslight
WebUI
ClientUI
What's New
Download Trial
Web Solution
Mobile Solution
Enterprise Solution
Custom Development
Blog
Community
Latest Development Blogs
ForumPostTopic
Browse By Tag
I have a hierarchical WebGrid that is unuseable due to slow performance. The actual query used to bind the grid takes ~6-7 seconds but the majority of time being the rendering. Using VirtualLoad w/ 200 page size, the load time is ~1:57min. Using Classing Paging w/ 200 page size, the load time is ~1:16 min. Decreasing the page size to 50, the load time is ~30 secs. Removing the hierarchy that is defined within the server-side code, the VirtualLoad w/200 page size loads in ~34sec. while the Classing Paging w/ 200 page size loads in ~29sec., and the 50 page size loads in ~ 15sec.
Please assist. Thanks.
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="TransList.ascx.cs" Inherits="Endurance.Re.FWB.Web.FWBWebControls.Transaction.TransList" %>
<%@ Register assembly="ISNet.WebUI.WebGrid" Namespace="ISNet.WebUI.WebGrid" TagPrefix="ISWebGrid" %>
<%@ Register assembly="ISNet.WebUI.WebDesktop" Namespace="ISNet.WebUI.WebDesktop" TagPrefix="ISWebDesktop" %>
<div class="ContentTemplateGridContent">
<CommonCtrl:EnduranceWebGrid runat="server" ID="grdTransList"
DefaultStyleMode="Elegant" UseDefaultStyle="True"
Width="100%" Height="100%"
EnableViewState="false" ViewStateStorage="None"
OnPreInitialize="grdTransList_OnPreInitialize"
OnInitializeDataSource="grdTransList_OnInitializeDataSource"
OnInitializeLayout="grdTransList_OnInitializeLayout"
OnInitializeRow="grdTransList_OnInitializeRow"
OnInitializePostback="grdTransList_OnInitializePostBack"
OnPrepareDatabinding="grdTransList_OnPrepareDataBinding"
OnExport="grdTransList_OnExport">
<LayoutSettings
Hierarchical="true" HierarchicalMode="Preload"
AutoHeight="True"
RowHeightDefault="22px"
AllowFilter="Yes"
AllowSelectColumns="Yes"
AllowSorting="Yes"
HideColumnsWhenGrouped="Default"
NewRowLostFocusAction="AlwaysPrompt"
ResetNewRowValuesOnError="False"
InProgressUIBehavior="ChangeCursorToHourGlass"
ApplyFiltersKey="Enter"
AllowColumnFreezing="Yes"
ShowFilterStatus="True"
VerboseEditingInformation="False"
FilterBarVisible="True"
CellPaddingDefault="0"
AlwaysShowHelpButton="False"
AllowExport="Yes" PagingExportMode="ExportAllData"
PagingMode="VirtualLoad" VirtualPageSize="200">
<FrameStyle>
<BorderSettings>
<Top Style="None" />
<Bottom Style="None" />
<Left Color="#6593cf" Width="1" Style="Solid" />
<Right Color="#6593cf" Width="1" Style="Solid" />
</BorderSettings>
</FrameStyle>
<HeaderStyle CssClass="WebGridHeaderStyle" />
<StatusBarStyle CssClass="WebGridStatusBarStyle" />
<StatusBarCommandStyle Active-CssClass="WebGridStatusBarCommandStyleActive"
Normal-CssClass="WebGridStatusBarCommandStyleNormal"
Over-CssClass="WebGridStatusBarCommandStyleOver" >
<Normal CssClass="WebGridStatusBarCommandStyleNormal" />
<Over CssClass="WebGridStatusBarCommandStyleOver" />
<Active CssClass="WebGridStatusBarCommandStyleActive" />
</StatusBarCommandStyle>
<FilterRowStyle CssClass="WebGridFilterRowStyle" />
<PreviewRowStyle CssClass="WebGridRowStyle" />
<RowStyle CssClass="WebGridRowStyle" />
<QuickFilterBarStyle CssClass="WebGridRowStyle" />
<RowHeaderStyle CssClass="WebGridRowHeaderStyle" />
<SelectedRowStyle CssClass="WebGridSelectedRowStyle" />
<EditFocusCellStyle CssClass="WebGridRowStyle" />
<FocusCellStyle CssClass="WebGridRowStyle" />
<LostFocusRowStyle CssClass="WebGridRowStyle" />
<NewRowStyle CssClass="WebGridRowStyle" />
<SortedColumnStyle CssClass="WebGridSortedColumnStyle" />
<AlternatingRowStyle CssClass="WebGridAlternatingRowStyle" />
<EditTextboxStyle CssClass="WebGridEditTextboxStyle" />
<FreezePaneSettings AbsoluteScrolling="True"
ActiveFrozenColumns="4"
ShowInContextMenu="False"
ShowSplitterLine="False"
MaxFrozenColumns="4"
SplitterLineColor="ActiveBorder"
SplitterLineWidth="1" />
</LayoutSettings>
<RootTable Caption="Transactions" DataKeyField="TransactionHeaderID" DataMember="TransactionList">
<Columns>
<ISWebGrid:WebGridColumn Caption="" DataMember="TransactionHeaderID" DataType="System.String"
EditType="NoEdit" Name="TransactionHeaderID" Width="0px" Visible="false" />
<ISWebGrid:WebGridColumn Caption="" DataMember="IsTransactionListProcessable" DataType="System.String"
EditType="NoEdit" Name="IsTransactionListProcessable" Width="0px" Visible="false" />
<ISWebGrid:WebGridColumn Caption=" " Name="TreatyProcessButton" DataMember="" HiddenDataMember="TransactionHeaderID" DataType="System.String"
Width="65px" ButtonText="Treaty Process" ColumnType="Template" EditType="NoEdit" NewRowEditType="NoEdit" Bound="true">
<ButtonStyle BackColor="AliceBlue">
<Padding Top="2px" Left="1px" Right="1px" Bottom="1px" />
</ButtonStyle>
<CellTemplate>
<img runat="server" id="imgTreatyProcess" name="imgTreatyProcess" src="~/Images/Buttons/process_off.gif" alt="Process the treaty"
border="0" style="padding-top: 1px;"
onclick="javascript:treatyProcess();" onmouseout="javascript:MM_swapImgRestore()" onmouseover="javascript:MM_swapImage(this.id,'','../../Images/Buttons/process_on.gif',1)" />
</CellTemplate>
</ISWebGrid:WebGridColumn>
<ISWebGrid:WebGridColumn Caption="" FilterEditType="NoEdit" ColumnType="Image"
EditType="NoEdit" Name="TransactionHeaderStatusIcon" Width="20px" />
<ISWebGrid:WebGridColumn Caption="Status" DataMember="TransactionHeaderStatusName" FilterEditType="TextBox"
EditType="NoEdit" Name="TransactionHeaderStatusName" Width="80px" />
<ISWebGrid:WebGridColumn Caption="Treaty" DataMember="MasterReference" FilterEditType="TextBox" DataType="System.String"
EditType="NoEdit" Name="MasterReference" Width="100px" />
<ISWebGrid:WebGridColumn Caption="Transaction" DataMember="AccountingTransactionTypeCode" FilterEditType="TextBox" DataType="System.String"
EditType="NoEdit" Name="AccountingTransactionTypeCode" Width="80px" />
<ISWebGrid:WebGridColumn Caption="Transaction Description" DataMember="TransactionHeaderDescription" FilterEditType="TextBox" DataType="System.String"
EditType="NoEdit" Name="TransactionHeaderDescription" Width="200px" />
<ISWebGrid:WebGridColumn Caption="Assigned To" DataMember="AssignedTo" FilterEditType="TextBox" DataType="System.String"
EditType="NoEdit" Name="AssignedTo" Width="100px" />
<ISWebGrid:WebGridColumn Caption="Assigned On" DataMember="AssignedOn" FilterEditType="CalendarCombo" DataType="System.DateTime"
EditType="NoEdit" Name="AssignedOn" Width="100px" />
<ISWebGrid:WebGridColumn Caption="Created By" DataMember="CreatedBy" FilterEditType="TextBox" DataType="System.String"
EditType="NoEdit" Name="CreatedBy" Width="100px" />
<ISWebGrid:WebGridColumn Caption="Created On" DataMember="CreatedOn" FilterEditType="CalendarCombo" DataType="System.DateTime"
EditType="NoEdit" Name="CreatedOn" Width="100px" />
<ISWebGrid:WebGridColumn Caption="" DataMember="TransactionHeaderStatusID" Name="TransactionHeaderStatusID" Visible="false" />
</Columns>
</RootTable>
</CommonCtrl:EnduranceWebGrid>
</div>
#region using
using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using ISNet.WebUI;
using ISNet.WebUI.WebDesktop;
using ISNet.WebUI.WebGrid;
using Endurance.Re.Common.Data;
using Endurance.Re.Common.Utility;
using Endurance.Re.FWB.Web.Controllers;
using Endurance.Re.FWB.Web.Classes;
using Endurance.Re.FWB.Data;
using Endurance.Re.FWB.Utility;
#endregion using
namespace Endurance.Re.FWB.Web.FWBWebControls.Transaction
{
/// <summary>
/// Transaction List class
/// </summary>
public partial class TransList : BaseUserControl
#region Constants
private const string VIEWSTATE_FILTERTYPE = "ViewState_FilterType";
private const string TOOLBAR_FUNCTIONS_CREATENEWTRANSACTION = "cmdCreateNewTransaction";
#endregion Constants
#region Variables
private Controllers.FWBWebControls.Transaction.TransListController _controllerTransList = null;
#endregion Variables
#region Properties
/// Transaction List Controller
public new Controllers.FWBWebControls.Transaction.TransListController Controller
get
if (this._controllerTransList == null) { this._controllerTransList = new Controllers.FWBWebControls.Transaction.TransListController(this.Page.UserID); }
return this._controllerTransList;
}
set { this._controllerTransList = value; }
/// Filter Type
public Data.TransactionList.FilterTypes FilterType
get { return (Data.TransactionList.FilterTypes)(this.ViewState[TransList.VIEWSTATE_FILTERTYPE] ?? Data.TransactionList.FilterTypes.MyRecent); }
set { this.ViewState[TransList.VIEWSTATE_FILTERTYPE] = value; }
/// Transaction List grid control's Refresh Interval
protected int RefreshTransListGridInterval
get { return (AppSettings.TransList_Refresh_Interval > 0) ? AppSettings.TransList_Refresh_Interval : 0; }
#endregion Properties
#region Constructors
/// TransList constructor
public TransList()
// Do nothing
#endregion Constructors
#region Event Handlers
#region Page
/// Handles the page's Load event
/// <param name="sender">Sender</param>
/// <param name="e">Event Arguments</param>
protected void Page_Load(object sender, EventArgs e)
// Initialize the page
this.InitPage((this.Page.IsPostBack == false));
#endregion Page
#region Controls
#region Transaction List Grid
/// Handles the TransList DataGrid control's OnPreInitialize event
protected void grdTransList_OnPreInitialize(object sender, EventArgs e)
// Load the Transaction List grid control's Hierarchical Object Relations
this.LoadTransListGridHierarchicalObjectRelations();
/// Handles the Transaction List grid control's OnInitializeLayout event
/// <param name="sender"></param>
/// <param name="e"></param>
protected void grdTransList_OnInitializeLayout(object sender, ISNet.WebUI.WebGrid.LayoutEventArgs e)
// Initialize
if (e == null) { return; }
e.Layout.ClientSideEvents.OnBeforeRequest = CommonConstants.JAVASCRIPT_COMMON_WEBGRID_SAVESCROLLPOSITION;
/// Handles the Transaction List grid control's OnInitializeDataSource event
/// <param name="e">Event arguments</param>
protected void grdTransList_OnInitializeDataSource(object sender, ISNet.WebUI.WebGrid.DataSourceEventArgs e)
// Get transaction data
e.DataSource = this.Controller.GetTransactionListData(this.FilterType, base.Page.CurrentMasterNumber, base.Page.CurrentMasterSequence, this.Page.UserID);
/// Handles the TransList DataGrid control's OnPrepareDataBinding event
protected void grdTransList_OnPrepareDataBinding(object sender, ISNet.WebUI.WebGrid.DataSourceEventArgs e)
// Load Transaction List grid control's hierarchical structure
this.LoadTransListGridHierarchicalStructure();
/// Handles the Transaction List grid control's OnInitializeRow event used to perform row level initialization.
protected void grdTransList_OnInitializeRow(object sender, ISNet.WebUI.WebGrid.RowEventArgs e)
/// Handles the Transaction List grid control's OnInitializePostBack event handler. Fired on a full or on the fly postback.
protected void grdTransList_OnInitializePostBack(object sender, ISNet.WebUI.WebGrid.PostbackEventArgs e)
/// Handles the Transaction List grid control's OnExport event
/// <param name="e">Event arugments</param>
protected void grdTransList_OnExport(object sender, ExportEventArgs e)
e.ReportInfo.EnableValueList = true;
e.ReportInfo.DisablePaging = true;
#endregion Transaction List Grid
#endregion Controls
#endregion Event Handlers
#region Methods
/// Initialize the page
/// <param name="initalize">Initialize</param>
private void InitPage(bool initalize)
/// Load the Transaction List grid control's Hierarchical Object Relations
private void LoadTransListGridHierarchicalObjectRelations()
// Defines object relationships between parent/child
ArrayList objectRelations = new ArrayList();
objectRelations.Add(new WebGridObjectRelation(
typeof(List<Data.TransactionList>), Data.Constants.SP_COL_TRANSACTIONLIST_TRANSACTIONHEADER_ID, Data.Constants.DATABASE_TABLE_TRANSACTIONQUEUE_NAME,
typeof(List<Data.TransactionQueue>), Data.Constants.SP_COL_TRANSACTIONLIST_TRANSACTIONHEADER_ID));
// Defines the Parent and Child Type information
// objectTypes contains 3 object array: The parent collection type, child item type, the
// primary keys of child collection Primary keys can be string (if only 1 primary key
// defined), or array of string for multiple primary keys scenario.
ArrayList objectTypes = new ArrayList();
objectTypes.Add(new object[] {
typeof(List<Data.TransactionList>), typeof(Data.TransactionList), Data.Constants.SP_COL_TRANSACTIONLIST_TRANSACTIONHEADER_ID});
typeof(List<Data.TransactionQueue>), typeof(Data.TransactionQueue), Data.Constants.SP_COL_TRANSACTIONLIST_TRANSACTIONQUEUE_ID});
this.grdTransList.SetObjectRelations(objectRelations, objectTypes);
/// Load the Transaction List grid control's hierarchical structure
/// <remarks>The RootTable is defined on the client while the child tables are defined here per Intersoft</remarks>
private void LoadTransListGridHierarchicalStructure()
if (this.Page.IsPostBack == false)
// Transaction Queue Child Table
this.grdTransList.RootTable.ChildTables.Add(Data.Constants.DATABASE_TABLE_TRANSACTIONQUEUE_NAME);
WebGridTable transactionQueue = this.grdTransList.RootTable.ChildTables[0];
transactionQueue.DataMember = Data.Constants.DATABASE_TABLE_TRANSACTIONQUEUE_NAME;
transactionQueue.DataKeyField = Data.Constants.SP_COL_TRANSACTIONLIST_TRANSACTIONQUEUE_ID;
// Transaction Queue's Status Icon
WebGridColumn transactionQueueStatusIcon = new WebGridColumn(Data.Constants.SP_COL_TRANSACTIONLIST_TRANSACTIONQUEUE_STATUS_ICON, "");
transactionQueueStatusIcon.ColumnType = ISNet.WebUI.WebGrid.ColumnType.Image;
transactionQueueStatusIcon.Width = new Unit("20px");
transactionQueue.Columns.Add(transactionQueueStatusIcon);
// Transaction Queue's Status Name
WebGridColumn transactionQueueStatusName = new WebGridColumn(Data.Constants.SP_COL_TRANSACTIONLIST_TRANSACTIONQUEUE_STATUS_NAME,
Data.Constants.SP_COL_TRANSACTIONLIST_TRANSACTIONQUEUE_STATUS_NAME, "Status");
transactionQueueStatusName.Width = new Unit("80px");
transactionQueue.Columns.Add(transactionQueueStatusName);
// Transaction Queue's Reference Value
WebGridColumn referenceValue = new WebGridColumn(Data.Constants.SP_COL_TRANSACTIONLIST_TRANSACTIONQUEUE_REFERENCE_VALUE,
Data.Constants.SP_COL_TRANSACTIONLIST_TRANSACTIONQUEUE_REFERENCE_VALUE, "Reference #");
referenceValue.Width = new Unit("100px");
transactionQueue.Columns.Add(referenceValue);
// Transaction Queue's Error Message
WebGridColumn errorMessage = new WebGridColumn(Data.Constants.SP_COL_TRANSACTIONLIST_TRANSACTIONQUEUE_ERRORMESSAGE,
Data.Constants.SP_COL_TRANSACTIONLIST_TRANSACTIONQUEUE_ERRORMESSAGE, "Error");
errorMessage.Width = new Unit("100%");
transactionQueue.Columns.Add(errorMessage);
// Transaction Queue's Status ID
WebGridColumn transactionQueueStatusID = new WebGridColumn(Data.Constants.SP_COL_TRANSACTIONLIST_TRANSACTIONQUEUE_STATUS_ID,
Data.Constants.SP_COL_TRANSACTIONLIST_TRANSACTIONQUEUE_STATUS_ID,
Data.Constants.SP_COL_TRANSACTIONLIST_TRANSACTIONQUEUE_STATUS_ID);
transactionQueueStatusID.Visible = false;
transactionQueue.Columns.Add(transactionQueueStatusID);
this.grdTransList.LayoutSettings.Hierarchical = true;
this.grdTransList.LayoutSettings.HierarchicalMode = HierarchicalOperation.Preload;
/// Default Implementation - does nothing as save is not required for this control.
public override void Save()
#endregion Methods
The virtual load enables more data to be retrieved from server transparently and virtually as users scroll the data forward. The newly retrieved rows, resulting in more information to be displayed in one central place, inside the WebGrid. By default, the classic paging will use Automatic data retrieval mode. In automatic mode, WebGrid determines the total datasource rows based on the given datasource and display the current page appropriately.
When using virtual load, clicking on “Load More Data” icon will add more data to be rendered in the page, while the classic paging mode will keep the number of displayed row.
To disable WebGrid’s data caching
For more information regarding on how to improve performance using designer, please check WebGrid's documentation.
This issue is actually not WebGrid’s issue. It is caused by the rendering engine that belongs to the browser itself. Render a table that has thousands of rows is not that easy for web application. Not only WebGrid, but I believe event an HTML table itself.
You could improve WebGrid’s performance by disable WebGrid’s data caching, set PagingMode to Virtual Load and set WebGrid’s ViewStateStorage to none. Another option that you may try is probably the load on demand data retrieval concept. Child rows data of its parent row will not be rendered to client on each loaded table. The child rows of a table will be retrieved transparently when users click on “+” sign to expand the child rows. This results in efficient information delivery by displaying necessary information and load more information transparently when needed, all without leaving the current state of the working page.
Hope this helps.
This issue is actually not WebGrid’s issue. It is caused by the rendering engine that belongs to the browser itself. Render a table that has thousands of rows is not that easy for web application. Not only WebGrid, but I believe event an HTML table itself.You could improve WebGrid’s performance by disable WebGrid’s data caching, set PagingMode to Virtual Load and set WebGrid’s ViewStateStorage to none. Another option that you may try is probably the load on demand data retrieval concept. Child rows data of its parent row will not be rendered to client on each loaded table. The child rows of a table will be retrieved transparently when users click on “+” sign to expand the child rows. This results in efficient information delivery by displaying necessary information and load more information transparently when needed, all without leaving the current state of the working page.Hope this helps.
Did you even read my thread? First of all, the VirtualLoad is MUCH slower by over ~45 seconds vs ClassicPaging. Furthermore, the ViewStateStorage is set to None per the markup I posted. Can you elaborate on how to disable the Data Caching?
In regards to your comment about this not being a WebGrid issue but a browser issue. I strongly disagree. It should not take nearly 2 minutes to load 3,500 records w/ a 200 page size. There is a tremendous difference in performance just changing from VirtualLoad to ClassicPaging and from changing the page size from 200 to 50. Why would changing the page size from 200 to 50 result in over a ~46 second difference using ClassicPaging? Why does the rendering differ soo much between these settings? I work with other 3rd party controls such as Telerik, Infragistics, and even the base ASP DataGrid and *NONE* of them take nearly 2 minutes to load only 3,500 records w/ a page size of ~200 so I am not sure what those competitor products are are doing different.
or
Choose this if you're already a member of Intersoft Community Forum. You can link your OpenID account to your existing Intersoft Social ID.
Choose this if you don't have an Intersoft account yet. Your authenticated OpenID will be automatically linked to your new Intersoft account.
Enter your Wordpress Blogname