这是一个老话题,但我想我应该分享一下我最近为修复 IE 7 中由 WebForm_InitCallback 引起的长时间运行脚本错误所做的工作。
我有一个包含 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] = "&";
}
}
最终,WebForm_InitCallback 在我的 IE 7 机器上的运行时间从 27 秒缩短到了 4 秒。