GridView, performance and search-engines (SEO)
Developing a fast and search-engine friendly GridView (.NET 2.0)
|
The ASP.NET GridView is a powerful and userfriendly control for displaying a table
of data. It has nice features like
sorting, paging, databinding or templatefields.
When loading a large amount of data, the paging feature can be used. But this leads to the
following problems:
- You have to get all the needed data at once and store it for paging. Most developers use the Session-object to
store the needed data, which leads to memory problems when many users access the page.
- The links for paging uses javascript which is not followed by the most search-engines. The result is,
that only the links appearing on the first page of your GridView are indexed by search-engines.
To avoid this problems, you have to:
- Get only the data you need for one page from database.
- Implement a custom paging that uses GET-parameters and no javascript.
How this can be done is the topic of this article.
The standard
Here is a sample GridView with standard-implemenation that receives the data from
a method
GetData() : IList<String> It has a PageSize of 5 and a Pager with
First, Next, Previous and Last links:
| Item |
| 243833a1-1682-452b-84f8-51bf6bd3e976 |
| f613b2a1-197a-4cfb-a05e-57039e0978c8 |
| 16206d2f-0eb3-47d2-a7d6-0e472da0bf6f |
| fb2963a3-9a55-433b-8776-06c51abe8321 |
| 6a4c0c57-7b31-4ca5-98ee-a2304e46a583 |
|
When moving the mouse over the links in the footer you can see the javascript that
is executed when clicking. This is not very search-engine-friendly. The other drawback
is, that the call GetData gets 100 items from the database but we need only
5 rows.
Enhancing the GridView
When enhancing the GridView to become fast and search-engine-friendly for
large amount of data, you would implement a custom servercontrol. In this article
we do not follow this approach, we just show inner implementation-details to achieve
the enhancements. Here are the steps:
-
Add a GridView from toolbox to the aspx-page
- Set AllowPaging to false
- Set the width of the GridView
- Add a DIV with a ASP:Literal below the GridView (DIV with same size as the GridView)
- Change you dataaccess-method so that you receive only the rows you need and the
total number of rows
- Bind your GridView to the rows you received
- Add the links for paging to the Literal below the GridView
Okay, the first 3 steps are easy. Now for
step 4. The DIV could look like this:
<DIV style="width: 400px; border: solid 1px #666666">
<ASP:Literal ID="myPager" runat="server"></ASP:Literal>
</DIV>
The literal will hold the HTML-links. We will add these programmatically.
Step 5: Change the signature and implementation of the
GetData-method:
IList<string> GetData(
int currentPage,
int rowCount,
ref int totalRowCount )
{
// 1. get only the data from currentPage to rowCount
// 2. make a call that gets the number of all rows and store it in totalRowCount
// return the IList<string> with all results for one page
}
Step 6: Binding is the same as before:
int total = 0;
// we have to store this before from a GET-param "page"
int currentPage = ViewState["page"];
gridView.DataSource= GetData( currentPage, gridView.PageSize,
ref total );
gridView.DataBind();
// we store the totalRowCount cause we will need it when
displaying the links
ViewState["Total"] = total;
Step 7: Adding the HTML-links for paging
For this step we need to add HTML-links programmatically. For demonstration we only
add a previous and a next link.
Before we can do this, we have to store the GET-param "page" in the ViewState. If
it is not set, we set it to 1. The methods
SetPage and
DisplayPager
are called during
Page_Load:
private void
SetPage() {
if (Request["Page"] == null)
ViewState["Page"] = 1;
else
ViewState["Page"] = Request["Page"].ToString();
}
Then the pager can be created. Each link in the pager gets the GET-param "page".
This parameter is reused then by the method
GetData to retrieve the rows
we want to display.
private void DisplayPager() {
int total = Convert.ToInt32(ViewState["Total"]);
int page = Convert.ToInt32(ViewState["Page"]);
int lastPage = (int)(total / gridView.PageSize
);
string pagerText = "";
if( page != 1 )
pagerText += GetUri( Request.Path, page - 1 );
if( page < lastPage )
pagerText += GetUri( Request.Path, page + 1 );
myPager.Text = pagerText;
}
public string
GetPagerUri(
string url,
int page ) {
string result = "<a href='"
+ url + "?page" + page + "'>" + page + "</a>" ;
return result;
}
Now we have a GridView that can load large amount of data in little chunks on demand
and has a pager with links that can be found by search engines like google or yahoo.
Try it, it is not hard to implement.