代码之家  ›  专栏  ›  技术社区  ›  Aistina

为什么这段Javascript代码这么慢?

  •  2
  • Aistina  · 技术社区  · 16 年前

    我有一段Javascript代码,在InternetExplorer中每次调用大约需要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
    

    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(""); 
    }; 
    

    编辑:

    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();
    }
    
    3 回复  |  直到 16 年前
        1
  •  10
  •   Aistina    16 年前

    好吧,你不会相信的。我刚刚尝试删除以下行:

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

    它将平均运行时间减少到了三分之二毫秒。我通过分析toString调用非常快,因此显然设置window.location.href非常慢(几百毫秒!!!)。呸,我讨厌你。

    注意:这是一个干净的Internet Explorer安装,我没有疯狂的工具栏来减慢我的浏览器。

        2
  •  2
  •   Grzegorz Gierlik    16 年前

    似乎您存储了某些表单中的字段。

    而不是使用 document.getElementById() 要获取表单的每个元素,请尝试直接获取表单元素的值:

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

    哪里 formName 价值何在 name 属性 form 标签和 currentTab 价值何在 名称

    编辑:

    当我在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;
    }
    

    有很大的不同。

    在过去的十年里,恐怕没有什么变化。

        3
  •  1
  •   Mark    16 年前

    window.location.href 线可能是其中之一 input 或导致延迟的导航(如buggy浏览器工具栏)。

    顺便说一句,它在我的测试页面上运行得很好,但可能是因为您有一个更大的DOM。