Freigeben über


Fix: UpdatePanel Async Postbacks Slow in Internet Explorer

We've seen a few issues recently where customers were experiencing very slow async postbacks via an UpdatePanel, but only in Internet Explorer. Other browsers worked fine. (When I say "very slow", I mean in the neighborhood of 30 seconds!) The cause for this isn't a mystery to us.

Because of the way our HTML viewer (mshtml.dll) was designed, Internet Explorer is slow to iterate through large DOM collections. As it happens, the PageRequestManager class has a method called _destroyTree that does just that. It uses a for loop to iterate through all of the DOM nodes in the UpdatePanel's DIV. It does this on the client (the browser) before the request to the Web server is ever kicked off, and if you have a large DOM in your UpdatePanel, you might see a very long delay in Internet Explorer when this occurs.

If you're experiencing this kind of problem, I have good news. We've fixed this for the next version of ASP.NET, and we also have some code that you can use in your applications now to mediate the problem. You can find the updated code in our Knowledge Base at https://support.microsoft.com/?kbid=2000262.

Update 9/29/2009:
Removed the code from this blog post and referenced KB instead. We did this so that we can service the KB article without having to update this post in the future.

Comments

  • Anonymous
    June 18, 2009
    Hey, The code is broken. Opening curly brace of function body is missing and it gives JS error on the page. Looking forward for the proper code. Thanks in advance. Regards,

  • Anonymous
    June 19, 2009
    Sorry about that, Velio. Must have been a stray keystroke when I transferred it over. I've fixed it. Jim

  • Anonymous
    June 20, 2009
    Great job and tremendous piece of code, Jim. Initial usage and tests shows fantastic improvements on UpdatePanel performance. Regards

  • Anonymous
    June 22, 2009
    Thanks, Velio. The credit goes to our product group. I appreciate the update. Jim

  • Anonymous
    July 19, 2009
    This is really great. Yes it save a lot of loading page in update panel. Thank you very much

  • Anonymous
    August 21, 2009
    This is fantastic, my web page works like a dream now.   I have been delaying a release of a whole batch of changes due to slow postbacks and you have just saved me from rewriting the whole page using webservices and other time consuming developments.  Great stuff.

  • Anonymous
    September 29, 2009
    I am getting a js error 'nodetype' is null or not an object. Any thoughts?

  • Anonymous
    September 29, 2009
    Peter, Do you have a URL or can you share your page? Jim

  • Anonymous
    September 30, 2009
    No I do not. I did see that you had updated code in your Knowledge Base article and changed it. That fixed the error but my update panels seem even slower. I am not even hitting a DB or anything. Just updating labels with user selections in a form, kind of a summary of what was selected. We use IE6 as this company has not even updated to IE7 yet. Although it is slow in IE7 and 8 as well. Probably just my code. It is instantaneous on my development machine. I was surprised at how slow it is on the live server. It kind of makes it useless now. Oh well, live and learn.

  • Anonymous
    September 30, 2009
    Couple of things, Peter. First of all, if the code is entered correctly, you shouldn't get an error whether you're using the latest updated code or the previous code. All I can guess is that there must have been a typo. If you are still experiencing slowness, it's not caused by this issue. If you want assistance in tracking it down, you can open a support incident with us and we can help. Jim

  • Anonymous
    September 30, 2009
    Well Jim, I triple checked the code and kept getting the error. It obviously did not like something in the page. There was no typo, but thanks for assuming I am an idiot. The latest version does not throw the error. I do agree that something else is causing the slowness. I am afraid I cannot share any code with you to help fix this problem. Thanks for the offer. And it was a good idea to remove the code from here if it was not being updated.

  • Anonymous
    September 30, 2009
    Sorry you took it that way, Peter. I certainly wasn't assuming you were an idiot. Because the code was tested thoroughly and is in use by many people without any errors, I surmised that you might have a typo. I would never say someone is an idiot for having a typo! I've had pelnty of them myself. :) Everyone does. We are updating the code if we can improve on it, but we wanted to make sure to have it in only one place so that it didn't have to be updated twice. The code is available in the KB article linked on this post. Jim

  • Anonymous
    September 30, 2009
    I really did not take it that way, just my dry humor I guess. I'm just really bummed that it did not help me. I showed the boss the functionality on my machine (where it is super fast) and he loved it. Now it is pretty much useless on the live version until I speed it up. I'll keep checking for updates though. Thanks.

  • Anonymous
    September 30, 2009
    Understood, Peter. Funny thing is that when I originally posted this blog entry, I had a typo in the code. :) Yeah, this code is designed to work around a very specific issue. If you don't see slowness in Firefox, that's an indicator that it may be this issue. We have a lot of skill in troubleshooting performance issues like yours, so if you reach a dead end, open a case and we can help out! Jim

  • Anonymous
    September 30, 2009
    It is very crucial to put the JavaScript "immediately before the closing </body> element". In other cases it may not work. Thanks for the fix!

  • Anonymous
    November 19, 2009
    I am so happy I want to cry!  Thanks for solving this life-long (or at least the past year) dilemna.

  • Anonymous
    February 01, 2010
    The comment has been removed

  • Anonymous
    February 16, 2010
    Thank you so much. Awesome fix.

  • Anonymous
    February 26, 2010
    The comment has been removed

  • Anonymous
    March 15, 2010
    The comment has been removed

  • Anonymous
    March 15, 2010
    Thomas, You need to copy and paste the code from the article. What you're describing is not the code in our article. Jim

  • Anonymous
    March 15, 2010
    Drazen, If you have followed the directions in the article exactly and it hasn't resolved your problem, I can only surmise that your issue isn't caused by this problem. Without any data or troubleshooting, there's no way to determine what's wrong. If you can't resolve this on your own, we can certainly help, but you'll need to open a case via support.microsoft.com. Thanks. Jim

  • Anonymous
    March 15, 2010
    Thomas, I notice that what you are showing as "gs" should be "args". I'm not sure what's doing that. Is the code correct when you paste it but only wrong after your browse via your browser? Jim

  • Anonymous
    March 18, 2010
    Drazen's solution worked for me also. The disposetree script provided had no effect on the performance. I also found the root cause to be WebForm_InitCallback, which was taking 10-12 seconds to process the loop (700 elements containing roughly 100 select elements), and it is getting called after the disposeTree function. I am using Telerik's RadGrid and its RadScriptManager. I was able to confirm from various posts online that the underlying problem is the processing of the <select> element. If I use only text boxes in the grid, the result shows up in 1-2 seconds. I urge you to follow up on Drazen's solution before you completely disregard it and help us find a solution or at lest tell us the dangers of doing it, if any.

  • Anonymous
    March 21, 2010
    The comment has been removed

  • Anonymous
    May 24, 2010
    Thanks for this fix , its working like charm. Could i use ScriptManager.RegisterStartupScript for rendering this script at the bottom of page(before </form> tag), as i have around 40 pages in my website. I found a difference that when i put this script directly at the bottom(</body>) tag, that method was invoked only once. But through ScriptManager.RegisterStartupScript it was invoked for each and every postback. Is there any problem with registering the script like this?. Which one is correct ? Please help me.

  • Anonymous
    June 22, 2010
    How to use this code in a usercontrol module of DNN?

  • Anonymous
    March 19, 2011
    I'm use this code in DotNetNuke, I put it in Default page right after </body> or  an user control has this problem,  but nothing happen. This is my code: <body id="Body" runat="server" >    <dnn:Form id="Form" runat="server" ENCTYPE="multipart/form-data" >        <asp:Label ID="SkinError" runat="server" CssClass="NormalRed" Visible="False"></asp:Label>        <asp:PlaceHolder ID="SkinPlaceHolder" runat="server" />        <input id="ScrollTop" runat="server" name="ScrollTop" type="hidden" />        <input id="__dnnVariable" runat="server" name="__dnnVariable" type="hidden" />    </dnn:Form> <script language="javascript" type="text/javascript">      function disposeTree(sender, args) {        var elements = args.get_panelsUpdating();        for (var i = elements.length - 1; i >= 0; i--) {            var element = elements[i];            var allnodes = element.getElementsByTagName('*'),                length = allnodes.length;            var nodes = new Array(length)            for (var k = 0; k < length; k++) {                nodes[k] = allnodes[k];            }            for (var j = 0, l = nodes.length; j < l; j++) {                var node = nodes[j];                if (node.nodeType === 1) {                    if (node.dispose && typeof (node.dispose) === "function") {                        node.dispose();                    }                    else if (node.control && typeof (node.control.dispose) === "function") {                        node.control.dispose();                    }                    var behaviors = node._behaviors;                    if (behaviors) {                        behaviors = Array.apply(null, behaviors);                        for (var k = behaviors.length - 1; k >= 0; k--) {                            behaviors[k].dispose();                        }                    }                }            }            element.innerHTML = "";        }    } Sys.WebForms.PageRequestManager.getInstance().add_pageLoading(disposeTree); </script> </body> </html> Please help me! I need your help very much

  • Anonymous
    June 16, 2012
    Where should I put the code when using a master page? Should it be put before the </body> tag of the master page or someplace in the child page? If in the child page, where? Thank you.