Question

J'ai eu ce mauvais pressentiment sur la manière dont j'insère de plus grandes quantités de HTML. Supposons que nous ayons:

var html="<table>..<a-lot-of-other-tags />..</table>"

et je veux mettre cela dans

$("#mydiv")

auparavant, j'ai fait quelque chose comme

var html_obj = $(html); $("#mydiv").append(html_obj);

Est-il exact que jQuery analyse html pour créer des objets DOM? Eh bien, c’est ce que j’ai lu quelque part (UPDATE: je voulais dire que j’ai lu, jQuery analyse le code HTML pour créer l’arbre DOM entier à la main - c’est absurde, n'est-ce pas? , j'ai donc changé de code:

$("#mydiv").attr("innerHTML", $("#mydiv").attr("innerHTML") + html);

Se sent plus vite, n'est-ce pas? Et est-il exact que cela équivaut à:

document.getElementById("mydiv").innerHTML += html? ou jquery fait-il des trucs coûteux en arrière-plan?

J'aimerais bien apprendre des alternatives.

Était-ce utile?

La solution

innerHTML est remarquablement rapide, et dans de nombreux cas, vous obtiendrez les meilleurs résultats en définissant simplement ce paramètre (je voudrais simplement utiliser append).

Cependant, s'il y en a déjà beaucoup dans " mydiv " vous forcez alors le navigateur à analyser et à restituer tout le contenu (tout ce qui existait auparavant, ainsi que votre nouveau contenu). Vous pouvez éviter cela en ajoutant un fragment de document à " mydiv. " au lieu de cela:

var frag = document.createDocumentFragment();
frag.innerHTML = html;
$("#mydiv").append(frag);

De cette manière, seul votre nouveau contenu est analysé (inévitablement), contrairement au contenu existant.

EDIT: Mon mauvais ... J'ai découvert que innerHTML n'est pas bien pris en charge sur les fragments de document. Vous pouvez utiliser la même technique avec n'importe quel type de nœud. Pour votre exemple, vous pouvez créer le noeud de la table racine et insérer le innerHTML dans celui-ci:

var frag = document.createElement('table');
frag.innerHTML = tableInnerHtml;
$("#mydiv").append(frag);

Autres conseils

Essayez ce qui suit:

$("#mydiv").append(html);

Les autres réponses, y compris la réponse acceptée, sont plus lentes sur 2-10 x : jsperf .

La réponse acceptée ne fonctionne pas dans IE 6, 7 et 8 , car vous ne pouvez pas définir innerHTML d'un élément <table> en raison d'un bogue dans IE: jsbin .

Qu'est-ce que vous essayez d'éviter? & "Un mauvais pressentiment &"; est incroyablement vague. Si vous avez entendu & "; Le DOM est lent &"; et décidé d’éviter le DOM! &, alors c’est impossible. Chaque méthode d’insertion de code dans une page, y compris innerHTML, entraîne la création d’objets DOM. Le DOM est la représentation du document dans la mémoire de votre navigateur. Vous voulez que des objets DOM soient créés.

La raison pour laquelle les gens disent & "le DOM est lent"! " Cela est dû au fait que la création d’éléments avec document.createElement(), qui est l’interface officielle du DOM pour la création d’éléments, est plus lente que l’utilisation de la propriété innerHTML non standard dans certains navigateurs. Cela ne signifie pas que créer des objets DOM est mauvais, il est nécessaire de créer des objets DOM, sinon votre code ne ferait rien du tout.

La réponse à propos de l'utilisation d'un fragment DOM est sur la bonne voie. Si vous êtes constamment en train d'insérer des objets HTML dans le DOM, vous constaterez des améliorations de la vitesse d'utilisation du fragment. Ce post de John Resig explique assez bien: http://ejohn.org/blog/dom-documentfragments/

Le moyen le plus rapide d'ajouter des éléments

Le moyen le plus rapide d’ajouter à l’arborescence DOM consiste à mettre en mémoire tampon l’ensemble de vos ajouts dans un seul fragment DOM, puis à ajouter le fragment dom au dom.

C’est la méthode que j’utilise dans mon moteur de jeu.

//Returns a new Buffer object
function Buffer() {

    //the framgment
    var domFragment = document.createDocumentFragment();

    //Adds a node to the dom fragment
    function add(node) {
        domFragment.appendChild(node);
    }

    //Flushes the buffer to a node
    function flush(targetNode) {

        //if the target node is not given then use the body
        var targetNode = targetNode || document.body;

        //append the domFragment to the target
        targetNode.appendChild(domFragment);

    }

    //return the buffer
    return {
        "add": add,
        "flush": flush
    }
}


//to make a buffer do this
var buffer = Buffer();

//to add elements to the buffer do the following
buffer.add(someNode1);

//continue to add elements to the buffer
buffer.add(someNode2);
buffer.add(someNode3);
buffer.add(someNode4);
buffer.add(someN...);

//when you are done adding nodes flush the nodes to the containing div in the dom
buffer.flush(myContainerNode);

En utilisant cet objet, je peux rendre ~ 1000 éléments à l'écran ~ 40 fois par seconde dans Firefox 4.

Voici un cas d'utilisation.

Pour commencer, écrivez un script indiquant le temps nécessaire pour le faire 100 ou 1 000 fois avec chaque méthode.

Pour vous assurer que les répétitions ne sont pas optimisées (je ne suis pas un expert des moteurs JavaScript), modifiez le code HTML que vous insérez à chaque fois, par exemple, en mettant "0001" puis "0002", puis "0003". dans une certaine cellule de la table.

Je crée une chaîne géante avec, puis je l’ajoute avec jquery. Ça marche bien et vite, pour moi.

Vous dites être intéressé par des alternatives. Si vous consultez la liste des plugins jQuery liés à DOM , vous trouverez plusieurs sont dédiés à la génération programmée d’arbres DOM. Voir, par exemple, SuperFlyDom ou Créateur d’éléments DOM ; mais il y en a d'autres.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top