admin管理员组

文章数量:1344322

I have this piece of Javascript code, which takes about 600 ms on every call in Internet Explorer. The time taken in other browsers is negligble.

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

This is what the call tree looks like, from the IE8 profiler:

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

The StringBuffer implementation I'm using:

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

Edit: Updated code, takes 397 ms on average to run.

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

I have this piece of Javascript code, which takes about 600 ms on every call in Internet Explorer. The time taken in other browsers is negligble.

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

This is what the call tree looks like, from the IE8 profiler:

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

The StringBuffer implementation I'm using:

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

Edit: Updated code, takes 397 ms on average to run.

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();
}
Share Improve this question edited May 7, 2009 at 8:55 Aistina asked May 7, 2009 at 8:17 AistinaAistina 12.7k14 gold badges72 silver badges91 bronze badges 6
  • 12 Because IE is a whore. /question – user47322 Commented May 7, 2009 at 8:19
  • 1 Hah, couldn't agree more! But I think my boss will kill me if I just ignore IE :P – Aistina Commented May 7, 2009 at 8:24
  • How much time does it take if you remove the loop? (I know it will stop working but it helps in determining what part is causing the lengthy execution time) – James Commented May 7, 2009 at 8:35
  • So your question bees "how can I convince my boss this will work fine when deployed" :-) – Dead account Commented May 7, 2009 at 8:35
  • Removing the loop makes pretty much no difference. – Aistina Commented May 7, 2009 at 8:37
 |  Show 1 more ment

3 Answers 3

Reset to default 10

Okay, you're not going to believe this. I just tried removing the following line:

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

And it reduced the average runtime to two third of a millisecond. I know from profiling the toString call is very fast, so apparently setting the window.location.href is ultra slow (couple of hundred ms!!!). Bah, I hate IE.

Note: This is a clean install of Internet Explorer, and I have no crazy toolbars slowing down my browser.

Seems that you store fields from some form.

Instead of using document.getElementById() to get each element of form try to get value of form elements directly:

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

where formName is value of name attribute of form tag and currentTab is value of name attribute of form element (i.e. input, checkbox).

EDIT:

When I was using IE5 and IE5.5 in 2000 even change (store reference to form element in variable) from:

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

to:

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

made big difference.

I am afraid nothing has changed during last 10 years :(.

Have you tried menting out the "get all vars" section and the window.location.href line? It may be one of the inputs or navigation (e.g. buggy browser toolbar) that's causing the delay.

By the way, it works fine on my test page, but it may be that you have a much larger DOM.

本文标签: profilingWhy is this piece of Javascript code so slowStack Overflow