Gridview Pagination good or bad-Performance - asp.net

Is Gridview pagination bad?
Reason: 1.If javascript is disabled, it will not work.
2.Search engine will not be able to index(I don't know what exactly the reason behind this).
Can somebody provide some information?
EDIT:
Now I am coding it as :
protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
int newPagenumber = e.NewPageIndex;
GridView1.PageIndex = newPagenumber;
GridView1.DataSource = Session["myDataSet"];
GridView1.DataBind();
}

the default implementation of gridview pagination is the worst option for performance as well as SEO. because it loads all data rows from your data source even if its only displaying 10 rows. second, search engines do not index postbacks
however there are many workarounds to sort this problem. implement custom data source to get rid of reading all rows from your data source, and then build your custom control to support seo friendly pager controls (you can even use the new asp.net mvc framework for this quite well)
on a seperate note - i see your code above - this is the worst way to code. never save bulky data in sessions, you would quickly run out of memory if you have too many users... instead use a global cache application, save your most frequently read data in there and use it for display purpose

To clarify, are you saying that:
By default the paging controls in a GridView are LinkButtons, which use JavaScript to perform postbacks?
A page with a paginated GridView will only display n records at once (where n is your page size)?
Therefore your concern is that a search engine will only ever see the first n records on your page as it may not follow javascript links? Therefore this could be a concern for SEO if you wish all the records in your datasource to be indexed?
My solution to this would be to use a ListView control, instead, with a DataPager control that uses a QueryString field to pass page number by GET. This would be easily followable by an search engine bot.

Pagination is concept to avoid rendering all the content at a time in a page. This will help in reducing the total size of the page.
If you don't apply pagination to your gridview and your control contains thousands of rows then this will be a horrible experience for the user to wait for the page to load.
You can pull only the number of records that you need for a particular page from database. This will avoid the burden of fetching all the rows and then displaying only the ones that are necessary.

Related

RowCommand GridView took 6,7 seconds

I placed a GridView inside an update panel.
<asp:UpdatePanel ID="UpdatePanel4" UpdateMode="Conditional" ChildrenAsTriggers="true"
runat="server">
<asp:GridView ID="GridView_Overview" OnRowCommand="GridView_Layout_RowCommand" />
</asp:GridView>
</asp:UpdatePanel>
When the user press a button, the gridView will be filled up with a datatable:
GridView_Overview.DataSource = dataTable;
GridView_Overview.DataBind();
The dataTable contains more than 10000 records. Therefore, the binding process to the gridview took about 3,4 seconds.
When a row is selected in the gridview:
protected void GridView_Layout_RowCommand(object sender, GridViewCommandEventArgs e)
{if (e.CommandName.Equals("Select"))
{
int index = Convert.ToInt32(e.CommandArgument);
GridViewRow row = this.GridView_Overview.Rows[index];
Int64 pID = Int64.Parse(((Label)row.FindControl("ID")).Text); // abc
}
}
It took 5,6 seconds to perform GridView_Layout_RowCommand as above. What is the issue here? How can I improve the performance of selecting a row. If I discard the //abc code line then it is fast but then I can not get the ID value for further process.
Thanks in advance.
This problem is occurring because the asynchronous postback from the UpdatePanel will be triggered only after walking through the entire DOM. If you're adding over 10000 records to the page then your DOM is going to be huge and the delay will be significant.
The key to solving your problem is destroying the GridView DOM elements before the postback is triggered. This way, there will be much less DOM to be traversed.
See this blog post for some tips on handling the situation: Slow performance of a GridView inside an UpdatePanel
At the very least, including even the most basic form of paging will improve client-side performance as it will reduce the number of DOM elements added to the page. For maximum results, you'll want to have a solution that also only selects each page of data so that you don't need to return 10000 records but only display a subset.
Alison's answer mentions this, and I want to reinforce the point: you really should not display 10,000 records at a single time. Even with minimal HTML (which the GridView won't generate, because it's creating long server-side IDs), you've created a huge page for your users to download.
You've also created a lot of work for your server -- work that may be (is?) entirely unnecessary. How many of your users do you expect to go through all 10,000 records at once? That's asking a lot, even for extremely dedicated people.
The best way to increase performance and make your page more usable is to add paging. It's a little complicated, but paging will reduce the size of the data your server has to transfer, and significantly reduce the amount of time spent by the browser on the AJAX call and rendering the HTML.
MSDN has an overview up here. Essentially, when the page changes, you'll want to do something like this (note: not exact code):
byte pageSize;
protected override void OnInit(EventArgs e)
{
pageSize = 50;
}
void GridView_Overview_PageIndexChanging(Object sender, GridViewPageEventArgs e)
{
GridView_Overview.DataSource = dataTable.Skip(pageSize * e.NewPageIndex).Take(pageSize);
GridView_Overview.DataBind();
}
You'll have to include a using System.Data.Linq; directive at the top of your code-behind page. You may want to let the user select the number of items per page, in which case you'd get pageSize from a control on the page, instead of setting it in OnInit as I did.
Check what the client is sending back to the server using the development tools of the browser. What you should check specifically is the size of the post when clicking.
If my suspicions are right (can't imaging they've fixed it since I last tried and scrapped it) it's posting the entire viewstate back to the server and returning it again to keep the control state server-side intact which in your case with 10,000 row will be quite substantial.
The only way to limit the effect of this behaviour is to add paging and get the pages from the data source each time the user is shifting grid page i.e. don't bind the entire data set to the grid at once.

(New to ViewStates) What is the best way(s) to save a dynamically generated control into the viewstate?

I am creating a web application in Asp.net and I'm still fairly new. I'm just starting to wrap my head around the basics of the ViewState. In my application, people are searching through a database and I give them ways to narrow their search. When they have entered a valid search constraint (ex: date past 10/1/11) I dynamically add another set of controls allowing them to add another constraint. I want to save the contents of the previous constraint (a set of Controls) so that I can still have it on the webpage when they enter the next constraint.
If it makes any difference, one constraint set consists of a drop-down list of attributes, a few literal control, and one or two text fields depending on what attribute was chosen from the drop down list.
How would I go about this?
Thanks so much guys.
The easiest way to track viewstate for dynamic controls is to recreate the controls in OnInit and assign the same ID to the controls every time the page is posted back. If the controls are assigned the same ID each time they're created, when the ViewState is loaded, the controls will be repopulated.
protected override void OnInit(EventArgs e)
{
TextBox txt = new TextBox();
txt.ID = "txt1";
this.Controls.Add(txt);
}
EDIT
To make things easier, try using the DynamicControlsPlaceHolder. Just put the control on the page, and it will persist the controls and their values behind the scenes:
http://www.denisbauer.com/ASPNETControls/DynamicControlsPlaceholder.aspx
Check out this link:
https://web.archive.org/web/20210330142645/http://www.4guysfromrolla.com/articles/092904-1.aspx
http://www.codeproject.com/KB/viewstate/retainingstate.aspx
ViewState for dynamic controls is still maintained by the ASP.NET framework. Just make sure you add them during init or preinit, because viewstate is loaded for every control between the init and load stages.

how to dynamically generate page numbers and only load the corresponding page in the grid?

I need to load data in the gridview dynamically. That is when the user clicks the page number 2 then those records only has to be displayed.. I made a stored proc to return only those records whose page number is sent.. It will also return me the number of records too.. Now i want to create a placeholder which will create the page number buttons dynamically based on the number of records. Could anyone help me with the placeholder code.. ??
You need to use ObjectDataSource for custom paging in GridView.
Check these articles:
https://web.archive.org/web/20210510021915/http://aspnet.4guysfromrolla.com/articles/031506-1.aspx
If you love AJAX, give this a try:
http://dotnetslackers.com/articles/ajax/ASPNETAjaxGridAndPager.aspx
Quote from the page:
Paging
When working with large tables we
often required to use paging. Although
the DataGrid/GridView has built-in
support for paging they are pretty
much useless. Most developers often
refuse to use the built-in
functionality and use their own custom
logic which usually takes a start
index, page size and other additional
parameters and in turn returns only
the paged records with the total
number of records.
There are enough codes on the page to help you start the balll rolling.
i suggest you to use DataGrid instead. DataGrid has paging property

I am trapped in the UpdatePanel trap

I have a very big problem. I am making a CRM (Costumer Relationship Management) System in ASP.NET 3.5
I have based my entire project on DevExpress.com controls and the use of UpdatePanels.
Now one of my pages, which is a central page in the whole system, contains a very big amount of possibilities and therefore a big amount of UserControls.
Now my problem is that it's getting really really slow because of the fact that UpdatePanels are reposting the entire page and not only the update panel. We are talking sometime 3-4 seconds before a popup window appears :(
Is there any way I can refactor this entire system away from UpdatePanels without breaking my neck?
Are there anyway I can optimize my use of UpdatePanels?
The ViewState is also absolutely giant.
Any good ideas are welcome...
There's no way to get around posting the entire page using UpdatePanels. In lieu of redesigning the app here are a couple things I'd try:
Disable viewstate for any controls that don't need it
Set the UpdateMode="Conditional" for your user controls. This won't get around posting the entire page but it will cut down on rendering time a little. Only the content for the specific UpdatePanel will be updated in the browser.
Make sure your user controls have short IDs. The way ASP.NET webforms names controls in the html these IDs get repeated quite a bit if you have a lot of server controls. Same goes for naming master page placeholders. I once cut a large page to half the size by renaming user controls and placeholders.
Since you're a DevExpress user, you might consider taking a little time to learn their CallbackPanel which will allow you to do asynchronous processing without the overhead of the UpdatePanel.
Alternatively (someone please correct me if I'm wrong) but if all of the postbacks are asynchronous (i.e. in an UpdatePanel), wouldn't it be theoretically possible to disable ViewState for the entire page (in the Page directive) without negative consequences? You'd have to test it completely off course, but it's worth a shot.
You'll have to replace some of the postbacks contained in your update panels with real AJAX calls, i.e. send only the data that is required for the action to the server and get back only what's required to update the view, getting rid of the postback and the UpdatePanels.
(You'll notice my use of the terms 'action' and 'view' - yes, I am an MVC fan. The situation you are in is typical of the mess that is easily got into using WebForms and the ASP.NET AJAX controls.)
I must be missing something. Why is your updatepanel is reloading the entire page. The point of an updatepanel is to refresh only what is in that panel, isn't it? Thanks for the explanation. I guess we're talking about reposting the page and not redrawing the panel as I thought.
Try turning off ViewState, especially for grids.
What kind of control is most common on your page? Try replacing those with your own lightweight UserControl or Server Control that does not use ViewState or ControlState
For all Interested I want to add a solution on how to get rid of the Viewstate data on clientside. It does give the server an extra load but if you are in the same situation as me and have a lot of server power and need to take the load of the clientside this is nice.
Let all your pages Derive from BasePage.cs looking like this
public class BasePage : System.Web.UI.Page
{
protected override void SavePageStateToPersistenceMedium(object viewState)
{
string vsKey = String.Format("VIEWSTATE_{0}_{1}_{2}", base.Session.SessionID, Request.RawUrl, DateTime.Now);
Session.Add(vsKey, viewState);
ClientScript.RegisterHiddenField("__VIEWSTATE_KEY", vsKey);
}
protected override object LoadPageStateFromPersistenceMedium()
{
string vsKey = Request.Form["__VIEWSTATE_KEY"];
return Session[vsKey];
}
}
Now you have a key to the viewstate data session instead of the viewstate in your code...
Works like a charm for me on a website with 1000-1200 daily visitors as well.

ASP.net GridView's ViewStates

I'm using a Gridview to hold records that user can click on the checkbox in each record for indication that he/she want to save that record(after editing the data) and user can select as many records as they want and save them all at once.
In the code behind, I'll loop thour the gridview and look for the checkbox to save the record. If I disable the Gridview's view state. I can't loop it but if i enabled the gridview's viewstate then the gridview view state can go as high as 1mb and beyond.
what will be the best way to reduce the viewstate on this girdview control or is my approach is wrong?
If you can't reduce the size of your viewstate you could try an alternate solution. You can store your viewstate on the server. This blog post shows how to implement this:
Reducing the page size by storing ViewState on Server
I've implemented something similar to this on a page that had a huge viewstate and it worked great. I would try to optimize the viewstate before moving to something like this since it is creating a bit of overhead.
I think I used this article (it's been a while) and had to modify it for SQL as this uses the filesystem:
Persisting View State to the File System
If you're open to the idea you might want to consider implementing custom paging to reduce the number of records returned. Perhaps start with the default paging but that returns all records. If you want better performance custom paging is the way to go.
Some helpful material:
Efficiently Paging Through Large Amounts of Data
GridView ObjectDataSource LINQ Paging and Sorting
Improve GridView Performance by Delegating Paging to SQL Server
I agree with Alex. You could also ues a temp table to hold the data. I used this scenario on a project and it works fine. You could also use caching, but again that's puting the load on the web server (unless you have some sort of distributed caching).

Resources