簡體   English   中英

為什么這段Javascript代碼這么慢?

[英]Why is this piece of Javascript code so slow?

我有這段Javascript代碼,在Internet Explorer的每次調用中大約需要600毫秒。 其他瀏覽器所用的時間可以忽略不計。

var _nvs_currentTab;
var _nvs_zoomfield;
var _nvs_centerfield;
var _nvs_globsearch;
var _nvs_category;
var _nvs_favsonly;
var _nvs_wishonly;
var _nvs_friendfavsonly;
var _nvs_newitemsonly;
var _nvs_globsearchOld;
var _nvs_catOld;
var _nvs_favsonlyOld;
var _nvs_wishonlyOld;
var _nvs_friendFavsonlyOld;
var _nvs_newItemsOnlyOld;

function saveState()
{
    if (!_nvs_currentTab)
    {
        var f = document.getElementById;
        _nvs_currentTab = f('currentTab');
        _nvs_zoomfield = f('zoomfield');
        _nvs_centerfield = f('centerfield');
        _nvs_globsearch = f("globsearch");
        _nvs_category = f("category");
        _nvs_favsonly = f("favsonly");
        _nvs_wishonly = f("wishonly");
        _nvs_friendfavsonly = f("friendfavsonly");
        _nvs_newitemsonly = f("newitemsonly");
        _nvs_globsearchOld = f("globsearchOld");
        _nvs_catOld = f("categoryOld");
        _nvs_favsonlyOld = f("favsonlyOld");
        _nvs_wishonlyOld = f("wishonlyOld");
        _nvs_friendFavsonlyOld = f("friendFavsonlyOld");
        _nvs_newItemsOnlyOld = f("newItemsOnlyOld");
    }

    // get all state vars
    var navState= new Object();
    navState.page = currentPage;
    navState.currentTab = _nvs_currentTab.value;
    navState.zoomfield = _nvs_zoomfield.value;
    navState.centerfield = _nvs_centerfield.value;
    navState.globsearch = _nvs_globsearch.value;
    navState.category = _nvs_category.value;
    navState.favsonly = _nvs_favsonly.checked;
    navState.wishonly = _nvs_wishonly.checked;
    navState.friendfavsonly = _nvs_friendfavsonly.checked;
    navState.newitemsonly = _nvs_newitemsonly.checked;
    navState.globsearchOld = _nvs_globsearchOld.value;
    navState.catOld = _nvs_catOld.value;
    navState.favsonlyOld = _nvs_favsonlyOld.value;
    navState.wishonlyOld = _nvs_wishonlyOld.value;
    navState.friendFavsonlyOld = _nvs_friendFavsonlyOld.value;
    navState.newItemsOnlyOld = _nvs_newItemsOnlyOld.value;
    // build new url with state
    var url = new StringBuffer();
    url.append("#");
    for (var i in navState)
    {
        if (i != "page")
            url.append("&");
        url.append(i).append("=").append(navState[i]);
    }
    // set it
    window.location.href = url.toString();
}

這是調用樹的樣子,來自IE8分析器:

saveState               1    615,00 ms
  f                    15      1,00 ms
  String.split          1      0,00 ms
    Array               1      0,00 ms
  Object                1      0,00 ms
  StringBuffer          1      0,00 ms
  append               64      0,00 ms
    Array.push         64      0,00 ms
  toString              1      0,00 ms
    Array.join          1      0,00 ms
  Object.valueOf       63      0,00 ms
  Function.toString    63      0,00 ms

我正在使用的StringBuffer實現:

function StringBuffer() { 
    this.buffer = []; 
} 

StringBuffer.prototype.append = function append(string) { 
    this.buffer.push(string); 
    return this; 
}; 

StringBuffer.prototype.toString = function toString() { 
    return this.buffer.join(""); 
}; 

編輯:更新的代碼,平均需要397毫秒才能運行。

var _nvs_currentTab;
var _nvs_zoomfield;
var _nvs_centerfield;
var _nvs_globsearch;
var _nvs_category;
var _nvs_favsonly;
var _nvs_wishonly;
var _nvs_friendfavsonly;
var _nvs_newitemsonly;
var _nvs_globsearchOld;
var _nvs_catOld;
var _nvs_favsonlyOld;
var _nvs_wishonlyOld;
var _nvs_friendFavsonlyOld;
var _nvs_newItemsOnlyOld;

function saveState()
{
    if (!_nvs_currentTab)
    {
        var _f = document.guideForm;
        _nvs_currentTab = _f.currentTab;
        _nvs_zoomfield = _f.zoomfield;
        _nvs_centerfield = _f.centerfield;
        _nvs_globsearch = _f.globsearch;
        _nvs_category = _f.category;
        _nvs_favsonly = _f.favsonly;
        _nvs_wishonly = _f.wishonly;
        _nvs_friendfavsonly = _f.friendfavsonly;
        _nvs_newitemsonly = _f.newitemsonly;
        _nvs_globsearchOld = _f.globsearchOld;
        _nvs_catOld = _f.categoryOld;
        _nvs_favsonlyOld = _f.favsonlyOld;
        _nvs_wishonlyOld = _f.wishonlyOld;
        _nvs_friendFavsonlyOld = _f.friendFavsonlyOld;
        _nvs_newItemsOnlyOld = _f.newItemsOnlyOld;
    }

    // build new url with state
    var url = new StringBuffer();
    url.append("#");
    url.append('currentPage=').append(currentPage);
    url.append('&currentTab=').append(_nvs_currentTab.value);
    url.append('&zoomfield=').append(_nvs_zoomfield.value);
    url.append('&centerfield=').append(_nvs_centerfield.value);
    url.append('&globsearch=').append(_nvs_globsearch.value);
    url.append('&category=').append(_nvs_category.value);
    url.append('&favsonly=').append(_nvs_favsonly.checked);
    url.append('&wishonly=').append(_nvs_wishonly.checked);
    url.append('&friendfavsonly=').append(_nvs_friendfavsonly.checked);
    url.append('&newitemsonly=').append(_nvs_newitemsonly.checked);
    url.append('&globsearchOld=').append(_nvs_globsearchOld.value);
    url.append('&catOld=').append(_nvs_catOld.value);
    url.append('&favsonlyOld=').append(_nvs_favsonlyOld.value);
    url.append('&wishonlyOld=').append(_nvs_wishonlyOld.value);
    url.append('&friendFavsonlyOld=').append(_nvs_friendFavsonlyOld.value);
    url.append('&newItemsOnlyOld=').append(_nvs_newItemsOnlyOld.value);
    // set it
    window.location.href = url.toString();
}

好的,你不會相信這一點。 我剛剛嘗試刪除以下行:

window.location.href = url.toString();

它將平均運行時間縮短到三分之一毫秒。 我知道從分析中調用toString是非常快的,所以顯然設置window.location.href是超慢的(幾百毫秒!!!)。 呸,我討厭IE。

注意:這是一個干凈的Internet Explorer安裝,我沒有瘋狂的工具欄減慢瀏覽器的速度。

似乎您從某種形式存儲字段。

而不是使用document.getElementById()來獲取表單的每個元素,嘗試直接獲取表單元素的值:

navState.currentTab = document.formName.currentTab.value;

其中formName是的值name的屬性form標簽和currentTab是有價值的name形式元素的屬性(即輸入,復選框)。

編輯:

當我在2000年使用IE5和IE5.5甚至更改(存儲對變量中的表單元素的引用)時:

for (i = 0; i < document.form.elements.length; i++) {
  values[i] = document.form.elements[i].value;
}

至:

var form = document.form;
for (i = 0; i < form.elements.length; i++) {
  values[i] = form.elements[i].value;
}

有很大的不同。

恐怕在過去10年里沒有任何改變:(。

您是否嘗試過評論“獲取所有變量”部分和window.location.href行? 它可能是導致延遲的input或導航(例如錯誤的瀏覽器工具欄)之一。

順便說一句,它在我的測試頁面上工作正常,但可能是你有一個更大的DOM。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM