這是一個老話題,但我想我應該分享一下我最近做了什麼來修復由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