2009-05-07 6 views
2

J'ai ce morceau de code Javascript, qui prend environ 600 ms à chaque appel dans Internet Explorer. Le temps pris dans les autres navigateurs est négligeable.Pourquoi ce morceau de code Javascript est-il si lent?

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

C'est ce que l'arbre d'appel ressemble, du profileur 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 

La mise en œuvre StringBuffer J'utilise:

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: code mis à jour, prend en moyenne 397 ms pour fonctionner.

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

Parce que IE est une prostituée./question –

+0

Hah, ne pouvait pas être plus d'accord! Mais je pense que mon patron va me tuer si j'ignore IE: P – Aistina

+0

Combien de temps cela prend-il si vous supprimez la boucle?(Je sais que ça va s'arrêter de fonctionner mais ça aide à déterminer quelle partie cause le long temps d'exécution) – James

Répondre

10

Ok, tu ne vas pas croire ce que je viens d'essayer de retirer la ligne suivante:..

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

Et il a réduit le temps d'exécution moyen à deux tiers d'une milliseconde.Je sais de profilage l'appel toString est très rapide, donc en définissant apparemment le window.location.href est ultra lent (quelques centaines de ms !!!) Bah, je déteste IE

Note: Ceci est une installation propre d'Internet Explorer, et je n'ai aucune barre d'outils folle qui ralentit mon navigateur.

+0

Possible, mais étrange. Avez-vous essayé: 'var s = url.toString();'? Ce serait une preuve d'attribution lente de la valeur 'window.location.href'. –

+0

Yup, essayé ça. C'est vraiment la ligne window.location.href. Je recherche sur Google pour le moment, mais bizarrement, je n'ai pas encore trouvé quelque chose lié, bien que beaucoup d'autres bogues IE étranges. – Aistina

+0

Y a-t-il une chance que ce soit un mauvais rapport d'outil alors? En changeant le href vous êtes essentiellement en train de sortir les jambes de JS, donc j'imagine que tous les paris pourraient être désactivés avec des outils de surveillance. – annakata

1

Avez-vous essayé de commenter la section « obtenir tous vars » et la ligne window.location.href? Ce peut être l'un des input s ou de la navigation (par exemple, la barre d'outils du navigateur buggy) qui provoque le retard. Par ailleurs, cela fonctionne très bien sur ma page de test, mais il se peut que vous ayez un DOM beaucoup plus important.

2

Semble que vous stockez des champs d'une certaine forme.

Au lieu d'utiliser document.getElementById() pour obtenir chaque élément de forme essayer d'obtenir la valeur des éléments de formulaire directement:

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

formName est la valeur de name attribut de la balise form et currentTab est la valeur de name attribut de élément de formulaire (c'est-à-dire entrée, case à cocher).

EDIT:

Quand j'utilisais IE5 et IE5.5 en 2000 changer même (référence du magasin pour former l'élément dans la variable) de:

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

fait une grande différence.

Je ne suis rien peur a changé au cours des 10 dernières années :(

+0

D'accord - la recherche DOM par rapport à la 'navigation' directe peut donner un coup de pouce assez rapide. – Anthony

+0

Hmm, cela a sauvé environ 200 ms. Pas mal, mais pas tout à fait satisfaisant. Je posterai le code mis à jour dans une édition. – Aistina

Questions connexes