Welcome to Professional ASP.NET - Chris Love's Official Blog Sign in | Join | Help

Chris Love's Official ASP.NET Blog

Chris Love's Helpful tips, tricks and pragmatic development knowledge for the ASP.NET world.
Add to Technorati Favorites


ASP Insider
Moving ViewState and Other Hidden Variables to the Bottom of the Page - Update

Earlier I wrote about a method of moving the ViewState to the bottom of the page.  The advantages of this are two fold, one is it helps with search engine optimization by getting non-essential content out of the top of the page.  Second since it is at the bottom of the page it helps the important content to render just a little bit faster.

I have an update to my render method that uses regular expressions to extract the hidden variables and move them to the bottom of the page.

    Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter)

        ExRender(writer)

    End Sub

 

    Private Sub ExRender(ByVal writer As System.Web.UI.HtmlTextWriter)

 

        Dim stringWriter As New System.IO.StringWriter

        Dim htmlWriter As New HtmlTextWriter(stringWriter)

        MyBase.Render(htmlWriter)

        Dim html As String = stringWriter.ToString()

 

        Dim mc As MatchCollection = Regex.Matches(html, "<[a-z:_][-a-z0-9._:]+((\s+[^>]+)*|/s*)/?>")

        Dim sViewState As String = String.Empty

        Dim sEventTarget As String = String.Empty

        Dim sEventAurgument As String = String.Empty

        Dim sBody As String = String.Empty

 

        For Each m As Match In mc

 

            If m.Value.Contains("__VIEWSTATE") Then

                sViewState = m.Value

                html = html.Replace(sViewState, String.Empty)

            ElseIf m.Value.Contains("__EVENTTARGET") Then

                sEventTarget = m.Value

                html = html.Replace(sEventTarget, String.Empty)

            ElseIf m.Value.Contains("__EVENTARGUMENT") Then

                sEventAurgument = m.Value

                html = html.Replace(sEventAurgument, String.Empty)

 

            End If

 

        Next

 

        html = html.Replace("</form>", String.Empty) _

            & sViewState & sEventTarget & sEventAurgument & "</form>" '& sBody

 

        writer.Write(html)

 

    End Sub

I extracted the method out of the event handler, just so I could do a little better long term code maintenance.  I am moving three hidden input variables to the bottom of the page, but will probably just change this to move every hidden input beofre too long.

A little explanation about what is going on.  If you are not familiar with Regular Expressions, I can not encourage the learning of the Regex object enough, it is magical.  I will not cover the actual expression, but note that the RegEx.Matches method returns a MatchCollection containing all the strings that match the given regular pattern.

I then iterate through the returned MatchCollection to get each match.  If the Value, or matched string, contains the id I am looking for, then I set the value to a string I defined to hold the tag.  Then I replace the string of text with an empty string to get it out of the HTML.  When I am done looping through the list of matches I then strip the Form close tag (</Form>) from the HTML and place my hidden variables, then append the form close tag back.

This example targets three specific hidden inputs, but I think I will finally settle on a solution that grabs all hidden input tags and moves them to the bottom of the form.  I am just taking steps as I can.  I actually will be discussing ViewState Optimization techniques in the coming days, so stay tuned.

Posted: Wednesday, December 06, 2006 2:28 PM

by Chris Love

Comments

Chris Love's Official Blog - Professional ASP.NET said:

In my continuing theme on reducing and eliminating the ViewState from ASP.NET pages I want to begin covering

# December 9, 2006 4:40 PM

Nitesh said:

hi,

In addition to the the ViewState filed , is it possible to move down all the javascript too...?

I have written the following code but getting error

Here is the code snippet

//Push Script block at the end of page.

           StringBuilder scriptBlock = new StringBuilder();

           StartPoint = html.IndexOf("<script");

           while (StartPoint >= 0)

           {

               EndPoint = html.IndexOf("</script>", StartPoint);

               string scriptInput = html.Substring(StartPoint, EndPoint - StartPoint + 9);

               scriptBlock.Append(scriptInput);

               html = html.Remove(StartPoint, EndPoint - StartPoint + 9);

               StartPoint = html.IndexOf("<script");

           }

           FormEndStart = html.IndexOf("</form>") - 1;

           if (FormEndStart >= 0)

           {

               html = html.Insert(FormEndStart, scriptBlock.ToString());

           }

           writer.Write(html);

plz help!!!!!!!.

# October 12, 2007 10:02 AM

niloy2000 said:

Hi Chris,

I am trying to use your solution with my web application in .NET 2.0 with Ajax. But it is giving parse exception when I try to make an Ajax postback.

Could you please tell me the tweak I need to do to work it for my Ajax enabled web application.

Thanks,

Niloy

# December 20, 2007 4:11 AM

Joe said:

I'm also experiencing problems on any page that contains .NET 2.0 Ajax components when I use any form of code that moves the viewstate data to the bottom of the page. Any ideas?
# October 7, 2008 9:57 PM

Chris Love said:

Joe,

I have had that issue as well. I just have not had enough time to work through the issue. The Accordian control seems to be the biggest offender, but I am not sure it is the ViewState causing the issue, but rather moving Hidden Fields. I did a quick work around by creating a page property, Public Property MoveHiddenFields() As Boolean, to indicate if I want to move the ViewState or not. In the render method I check this first before performing the operation.

I had also created a method to clean whitespace that that had some major issues with some controls as well, so I did the same thing there.

# October 8, 2008 11:41 AM

Chris Love said:

Nitesh,

yes it is possible, you just need to modify the regular expression. But I will warn you this will cause issues with some AJAX controls so be judicious. I decided to not do this because I was having way too many issues.

Dim sPattern As String = "<input type=""hidden"".*/*>|<input type=""hidden"".*></input>|<script .*>.*</script>"

TO me the real problem is far too many ASP.NET Web/AJAX controls register way too many inline script blocks and we need to find a good way to optimize this into a .js file to include.

# October 8, 2008 11:44 AM
Leave a Comment

(required) 

(required) 

(optional)

(required) 

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS