这是一个老话题,但我想我应该分享一下我最近做了什么来修复由WebForm_InitCallback引起的IE 7中长时间运行的脚本错误。
我有一个包含超过2000个表单元素的页面,并且在IE 7中导致长时间运行的脚本警告/浏览器冻结客户端。我们有其他页面有更多的表单元素,并且由于需要快速转向以提高性能,分页或其他选项不是选项。
我把范围缩小到WebForm_InitCallback,甚至进一步向下面一行:
element = theForm.elements[i];
通过保存到theForm.elements一个参考,而不是使用它来访问索引,我发现显著的性能提升。
var elements = theForm.elements;
for (var i = 0; i < count; i++) {
element = elements[i];
....
}
我做了一个jsperf来测试,因为我没想到每次都从没有要求细化如此骄人的收益差异。
除此之外,通过替换WebForm_InitCallbackAddField中的连接,将字符串添加到数组并在WebForm_InitCallback中的for循环完成并将其保存回__theFormPostData后,将它们连接在一起,从而找到了更好的性能。
这里是原来的两个功能,你会在WebResource看到:
function WebForm_InitCallback() {
var count = theForm.elements.length;
var element;
for (var i = 0; i < count; i++) {
element = theForm.elements[i];
var tagName = element.tagName.toLowerCase();
if (tagName == "input") {
var type = element.type;
if ((__callbackTextTypes.test(type) || ((type == "checkbox" || type == "radio") && element.checked))
&& (element.id != "__EVENTVALIDATION")) {
WebForm_InitCallbackAddField(element.name, element.value);
}
}
else if (tagName == "select") {
var selectCount = element.options.length;
for (var j = 0; j < selectCount; j++) {
var selectChild = element.options[j];
if (selectChild.selected == true) {
WebForm_InitCallbackAddField(element.name, element.value);
}
}
}
else if (tagName == "textarea") {
WebForm_InitCallbackAddField(element.name, element.value);
}
}
}
function WebForm_InitCallbackAddField(name, value) {
var nameValue = new Object();
nameValue.name = name;
nameValue.value = value;
__theFormPostCollection[__theFormPostCollection.length] = nameValue;
__theFormPostData += WebForm_EncodeCallback(name) + "=" + WebForm_EncodeCallback(value) + "&";
}
这里是我加入到我的网页,以覆盖它们的JavaScript。在添加WebResource之后并在调用WebForm_InitCallback之前插入此代码很重要。
var __theFormPostDataArr = [];
if (typeof (WebForm_InitCallback) != "undefined") {
WebForm_InitCallback = function() {
var count = theForm.elements.length;
var element;
var elements = theForm.elements;
for (var i = 0; i < count; i++) {
element = elements[i];
var tagName = element.tagName.toLowerCase();
if (tagName == "input") {
var type = element.type;
if ((type == "text" || type == "hidden" || type == "password" ||
((type == "checkbox" || type == "radio") && element.checked)) &&
(element.id != "__EVENTVALIDATION")) {
WebForm_InitCallbackAddField(element.name, element.value);
}
}
else if (tagName == "select") {
var selectCount = element.options.length;
for (var j = 0; j < selectCount; j++) {
var selectChild = element.options[j];
if (selectChild.selected == true) {
WebForm_InitCallbackAddField(element.name, element.value);
}
}
}
else if (tagName == "textarea") {
WebForm_InitCallbackAddField(element.name, element.value);
}
}
__theFormPostData = __theFormPostDataArr.join('');
}
WebForm_InitCallbackAddField = function (name, value) {
__theFormPostDataArr = [];
var nameValue = new Object();
nameValue.name = name;
nameValue.value = value;
__theFormPostCollection[__theFormPostCollection.length] = nameValue;
__theFormPostDataArr[__theFormPostDataArr.length] = WebForm_EncodeCallback(name);
__theFormPostDataArr[__theFormPostDataArr.length] = "=";
__theFormPostDataArr[__theFormPostDataArr.length] = WebForm_EncodeCallback(value);
__theFormPostDataArr[__theFormPostDataArr.length] = "&";
}
}
最终,我的IE 7机器上运行WebForm_InitCallback的时间从27秒到4秒。
安迪,这很糟糕,但我很久以前就放弃了更新小组,经过一段时间的痛苦之后,没有它,我更加快乐。祝你好运。 – 2010-03-04 20:49:52