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 can be slow to iterate through large DOM collections in certain scenarios. 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. Add the following script block immediately before your closing </body> element on the page experiencing the problem. (If you prefer to add it elsewhere on the page, make sure that the script appears after the ScriptManager control.)

<script language="javascript" type="text/javascript">
function disposeTree(sender, args)gs.get_panelsUpdating();
    for (var i = elements.length-1; i >= 0; i--) {
        var nodes = elements[i].getElementsByTagName('*');
        for (var j = 0; j < nodes.length; 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 = Sys.UI.Behavior.getBehaviors(node);
                for (var k = behaviors.length - 1; k >= 0; k--) {
                    behaviors[k].dispose();
                }
            }
        }
        elements[i].innerHTML = "";
    }
}

Sys.WebForms.PageRequestManager.getInstance().add_pageLoading(disposeTree);
</script>

After adding this code, you should no longer see the delay in your UpdatePanel's postbacks. If you do still see a delay, it's likely that you aren't encountering a problem due to the issue I've described in this post. In that case, give us a call and we can help you troubleshoot.

 

No Comments