Moving VIEWSTATE to the bottom of the page

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.
13 years ago
VIEWSTATE hidden field is often 10% of page size, and appears before my useful html, so I decided to move it. Most solutions on the web use modules, witch is a good way to archive this on the global site. I tried a lighter implementation, just applied to pages wich will be crawled by goggle and others robots.

You can see the result on http://www.extensions-hair.com]http://www.extensions-hair.com

Just replace Render method in NopCommerceStore/Controls/BaseNopPage.cs

protected override void Render(HtmlTextWriter writer)
{

    if (showExecutionTimer)
    {
        executionTimer.Start();
    }
    ////Modif NICO
    // Obtain the HTML rendered by the instance.
    StringWriter sw = new StringWriter();
    HtmlTextWriter hw = new HtmlTextWriter(sw);
    base.Render(hw);

    try
    {
        string html = sw.ToString();

        // Hose the writers we don't need anymore.
        hw.Close();
        sw.Close();

        string viewstate = null, /*postback = null,*/ onSubmit = null;

        // Find the viewstate.
        int startViewstate = html.IndexOf(@"<input type=""hidden"" name=""__VIEWSTATE""");
        if (startViewstate > -1)
        {
            // Find the first preceding div tab
            int startViewstateDiv = html.LastIndexOf(@"<div>", startViewstate);

            // If we find it, then move it.
            if (startViewstateDiv > -1)
            {
                // Find the first folowing /div
                int endViewstateDiv = html.IndexOf("</div>", startViewstateDiv) + 6;

                // Strip out the viewstate.
                viewstate = html.Substring(startViewstateDiv, endViewstateDiv - startViewstateDiv);

                html = html.Remove(startViewstateDiv, endViewstateDiv - startViewstateDiv);

            }
        }

        // Find the OnSubmit script.
        int startOnSubmit = html.IndexOf(@"function WebForm_OnSubmit()");
        if (startOnSubmit > -1)
        {
            // Find the first preceding script tag
            int startOnSubmitScript = html.LastIndexOf(@"<script type=""text/javascript"">", startOnSubmit);

            // If we find it, then move it.
            if (startOnSubmitScript > -1)
            {
                // Find the first folowing /script
                int endOnSubmitScript = html.IndexOf("</script>", startOnSubmitScript) + 9;

                // Strip out the doOnSubmit.
                onSubmit = html.Substring(startOnSubmitScript, endOnSubmitScript - startOnSubmitScript);

                html = html.Remove(startOnSubmitScript, endOnSubmitScript - startOnSubmitScript);

            }
        }

        // Find the end of the form and insert it there, since we can't put it any lower in the response stream.
        int formend = html.LastIndexOf(("</form>"));
        if (viewstate != null) html = html.Insert(formend, viewstate);
        if (onSubmit != null) html = html.Insert(formend, onSubmit);

        // Send the results back into the writer provided.
        writer.Write(html);
    }
    catch (Exception ex)
    {
        base.Render(writer);
        LogManager.InsertLog(LogTypeEnum.CommonError, "Moving ViewState and doPostBack to the end of the form!", ex);
    }

    if (showExecutionTimer)
    {
        executionTimer.Stop();
        RenderExecutionTimerValue(writer);
    }
}


I gess it will be a problem if someone submits this page before page is completly loaded, then I a also moved the submit script. But this is not perfect!
Does anyone have ideas to improve this script?
(sorry for my english... hope you understand :))
13 years ago
I like the idea of moving the view state to the bottom of the page.  This will greatly enchance the chances of a web crawler like google to read the content of the page.  Found this doing a google search:

using System.IO;

    protected override void Render(HtmlTextWriter writer)
    {
        StringWriter sw = new StringWriter();
        HtmlTextWriter htw = new HtmlTextWriter(sw);
        base.Render(htw);

        string html = sw.ToString();
        int startPoint = html.IndexOf(@"<input type=""hidden"" name=""__viewstate""");
        if (startPoint >= 0)
        {
            int endPoint = html.IndexOf("/>", startPoint) + 2;
            string viewStateInput = html.Substring(startPoint, endPoint - startPoint);
            int formEndStart = html.IndexOf("</form>") - 1;

            if (formEndStart >= 0)
                html = html.Insert(formEndStart, viewStateInput);
        }

        writer.Write(html);
    }
13 years ago
Yes I also found this script, and it was my starting point to do mine. My script moves the full div containing viewstate, and others hidden fields, and also the OnSubmit script

<div>
<input type="hidden" name="ctl00_ctl00_cph1_cph1_ctrlForumPostEdit_sm1_HiddenField" id="ctl00_ctl00_cph1_cph1_ctrlForumPostEdit_sm1_HiddenField" value="" />
<input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" />
<input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" />
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUJMzU2NDgxNzQxD2QWAmYPZBYCZg9kFgQCAQ9kFgQCAQ8WAh4HY29udGVudAW4AW5vcENvbW1lcmNlIGlzIHRoZSBvcGVuLXNvdXJjZSBlQ29tbWY2JTdWJzY3JpYmUFI2N0bDAwJGN0bDAwJGN0cmxIZWFkZXIkdG9wTG9naW5WaWV3Dw9kAgFkgaTu73NG43+fNcouB4qYPT/HHKA=" />
</div>


<script type="text/javascript"> 
//<![CDATA[
function WebForm_OnSubmit() {
if (typeof(ValidatorOnSubmit) == "function" && ValidatorOnSubmit() == false) return false;
return true;
}
//]]>
</script>


I also tried to move this script
<script type="text/javascript"> 
//<![CDATA[
var theForm = document.forms['aspnetForm'];
if (!theForm) {
    theForm = document.aspnetForm;
}
function __doPostBack(eventTarget, eventArgument) {
    if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
        theForm.__EVENTTARGET.value = eventTarget;
        theForm.__EVENTARGUMENT.value = eventArgument;
        theForm.submit();
    }
}
//]]>
</script>


but the variable theForm need to be declared and initialized on the top of the page. Perhaps we could separate this script in two parts, theForm would stay on the top, and doPostBack could be moved to the bottom... I will try.
13 years ago
I replaced the cs, viewstate is still on top.  It has been a while, maybe a step by step instructions.
13 years ago
I'm sorry I have no more instruction... just replace Render method with this one!
Verify you are in the correct file : NopCommerceStore project, Controls folder and BaseNopPage.cs file
Recompile your project
Deploy it

And it should work!
13 years ago
I think that moving the ViewState to the bottom of the page should be considered with care.
Please check this post:

http://www.mojoportal.com/Forums/Thread.aspx?pageid=5&mid=34&ItemID=1&thread=4268&pagenumber=1

I have to say that after doing a bit of research on the topic, I tend to agree with Joe.
13 years ago
7Spikes wrote:
I think that moving the ViewState to the bottom of the page should be considered with care.
Please check this post:

http://www.mojoportal.com/Forums/Thread.aspx?pageid=5&mid=34&ItemID=1&thread=4268&pagenumber=1

I have to say that after doing a bit of research on the topic, I tend to agree with Joe.


Yes, I agree with you, viewstate is essential in asp web forms technology and should be considered with care.

But if you look as this : http://googlewebmastercentral.blogspot.com/2010/04/using-site-speed-in-web-search-ranking.html you will see that viewstate is not your friend.

So I tried to remove it from the pages, overriding SavePageStateToPersistenceMedium method, it worked, but I had some bugs in logs, because some viewstates where missing for pages loaded from browser cache for example. I think this solution is definitely not stable and even dangerous.


That is the reason why I did not removed it from the page on this post, but only moved it to the bottom. Why?

"It is not clear if the engine would view the Viewstate variable as being equivalent to text and / or whether or not the search engines would view the prominence of the content any differently if it was preceded by the Viewstate variable. In other words, it may just ignore it, in which case the page content is pretty much equivalent with or without the variable as far as the search engines are concerned. And from a logical point of view, it makes a certain amount of sense. However, when it comes to Google and SEO in general, assumptions based on logic don't always pay the bills...lol.

My philosophy about SEO has always been to eliminate as many unknown variables in the process as possible. And while I may have convinced a few people based on these observations that the Viewstate variable has no effect on SEO, it is virtually impossible to set up a controlled test to determine the effect absolutely. And so, because the potential for issues exists, my opinion is, don't leave it to chance. Or in this case, don't leave it to Google to decide if the Viewstate variable harms your search rankings."


you can read full article on http://www.businessol.com/seo-blog/2008/04/mystery-of-viewstate-variable-does-it.html

So I have tried to move this famous viewstate, and I the result was correct.
I still have a potential issue : if a user get impatient and tries to post the form before the page finishes loading. Postback is performed before the page fully loads, it will usually cause the following error: Invalid postback or callback argument.


I will work on this issue, but for the moment, after 4 weeks of production and 120 orders here http://www.extensions-hair.com/, this case did not appear
13 years ago
my take on this is , it would be nice to have all hidden fields moved to the bottom. however, as some have mentioned, there is no clear statement on the impact and no clear documentation on how this might affect the engine.
what i do for now is what most ppl are doing, moving only scripts to the bottom of the page.
This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.