Quelle est la façon la plus efficace de créer des éléments HTML à l'aide de jQuery?

425

Récemment, j'ai fait beaucoup de fenêtres pop-up modales et quoi, pour lesquelles j'ai utilisé jQuery. La méthode que j'ai utilisée pour créer les nouveaux éléments sur la page a été dans une large mesure le long des lignes de:

$("<div></div>");

Cependant, j'ai l'impression que ce n'est pas la méthode la meilleure ou la plus efficace pour le faire. Quelle est la meilleure façon de créer des éléments dans jQuery du point de vue des performances?

Cette réponse a les repères des suggestions ci-dessous.

Darko Z
la source
1
Essayez également de supprimer des styles et voyez si cela accélère les choses. Je trouve que l'application CSS et les mises à jour ralentissent le plus sur les grandes pages pour moi.
CVertex
3
Méfiez-vous de l'optimisation prématurée - si vous ne faites pas cela pour des centaines d'éléments DOM à la fois, ou si vous utilisez de TRÈS anciens navigateurs, vous ne remarquerez probablement aucune différence dans les performances du navigateur.
Blazemonger
1
@Blazemonger Ce n'était pas tellement que j'avais besoin d' une méthode plus efficace pour créer des éléments DOM, mais la situation dans laquelle je me trouvais m'a fait réfléchir sur les alternatives et leur efficacité.
Darko Z
2
jQuery est une bibliothèque - vous encourrez presque toujours des frais de performance pour cette raison: c'est comme parler à quelqu'un via un interprète. À moins que vous ne vouliez utiliser du JavaScript brut, profitez de la rapidité avec laquelle il est possible d'écrire $ ('<div>') et d'accepter le résultat de performance.
Danny Bullis
1
jsben.ch/#/bgvCV <= ce benchmark devrait répondre à votre question
EscapeNetscape

Réponses:

307

J'utilise l' $(document.createElement('div')); analyse comparative montre que cette technique est la plus rapide. Je suppose que c'est parce que jQuery n'a pas à l'identifier comme élément et à créer l'élément lui-même.

Vous devriez vraiment exécuter des benchmarks avec différents moteurs Javascript et peser votre audience avec les résultats. Prenez une décision à partir de là.

strager
la source
16
jQuery "l'ajoute" à DOM? Où? Cela n'a pas beaucoup de sens pour moi - où irait le div?
strager
28
un div créé en jquery doit être ajouté comme en javascript. $ ('<div>') en soi n'est pas attaché au DOM jusqu'à ce que vous l'ajoutiez () à quelque chose.
Owen
6
@David - vous avez évidemment raison. Je noterai que j'ai ajouté le commentaire il y a environ 2 ans juste au moment où je commençais à apprendre jQuery. Vous auriez besoin de faire un appendTo, ... Parce que les commentaires étaient manifestement faux, je les ai supprimés.
tvanfosson
16
La référence de référence est excellente, mais elle teste également la création de dizaines de milliers d'éléments. Quand traiterez-vous JAMAIS avec autant d'éléments dans une situation typique? Il y a de fortes chances que vous ayez plus de soucis à vous faire que de créer un élément. document.createElement "A parcouru 39 682 fois en 0,097 seconde", tandis que $ ('<div>') "a exécuté 12 642 fois en 0,068 seconde". Je dirais que si quelque chose peut fonctionner des milliers de fois en moins d'une seconde, vous êtes en sécurité.
Danny Bullis
20
De plus, en utilisant $ (document.createElement ('div')); Je dirais que c'est moins efficace car il faut plus de temps pour écrire pour le bénéfice substantiellement minime que vous obtiendrez dans le navigateur si vous ne créez qu'un élément à la fois ici et là. Techniquement, jQuery lui-même est moins efficace en tant que bibliothèque en raison des coûts de recherche et des frais généraux que vous encourez en l'utilisant. Si quelqu'un est si déterminé à économiser de précieux millièmes de millisecondes en utilisant document.createElement au lieu de $ ('<div>'), alors il ne devrait pas utiliser jQuery:], car $ ('<div>') est l'une des raisons pour lesquelles vous l'utilisez!
Danny Bullis
163

personnellement, je suggère (pour plus de lisibilité):

$('<div>');

quelques chiffres sur les suggestions à ce jour (safari 3.2.1 / mac os x):

var it = 50000;

var start = new Date().getTime();
for (i = 0; i < it; ++i)  {
  // test creation of an element 
  // see below statements
}
var end = new Date().getTime();
alert( end - start );                

var e = $( document.createElement('div') );  // ~300ms
var e = $('<div>');                          // ~3100ms
var e = $('<div></div>');                    // ~3200ms
var e = $('<div/>');                         // ~3500ms              
Owen
la source
15
À partir des documents jquery: 'Lors de la création d'éléments uniques, utilisez la balise de fermeture ou le format XHTML. Par exemple, pour créer une plage, utilisez $ ("<span />") ou $ ("<span> </span>") au lieu de sans barre oblique / balise de fermeture. '
tvanfosson
6
@Owen, ce comportement est un bug, pas une fonctionnalité. Déchets entrants, déchets sortis - il se trouve que les déchets que vous recevez sont acceptables. Ne vous y fiez pas entre les versions de jQuery, sauf si la spécification de la fonction change.
strager
2
Comme prévu, voir des nombres similaires dans Mac OS X Chrome (100 ms pour createElement () contre 500 ms pour l'analyse de texte) et Mac OS X Firefox (350 ms contre 1000 ms). Merci d'avoir rédigé la boucle de test.
Annika Backstrom
3
@tvanfosson Cela a changé apparemment, dans la documentation actuelle, il est dit: "Lorsque le paramètre a une seule balise (avec balise de fermeture facultative ou fermeture rapide) - $ (" <img /> ") ou $ (" <img> " ), $ ("<a> </a>") ou $ ("<a>") - jQuery crée l'élément à l'aide de la fonction native createElement () JavaScript. "
metatron
3
@MarcStober Aucune infraction n'a été prise. Il est toujours là: http://api.jquery.com/jQuery/#jQuery2 . Les documents mentionnent une balise de fermeture facultative ou une fermeture rapide
metatron
155

Question:

Quelle est la façon la plus efficace de créer des éléments HTML à l'aide de jQuery?

Réponse:

Puisqu'il s'agit jQueryalors je pense qu'il vaut mieux utiliser cette approche (propre) (vous utilisez)

$('<div/>', {
    'id':'myDiv',
    'class':'myClass',
    'text':'Text Only',
}).on('click', function(){
    alert(this.id); // myDiv
}).appendTo('body');

DEMO.

De cette façon, vous pouvez même utiliser des gestionnaires d'événements pour l'élément spécifique comme

$('<div/>', {
    'id':'myDiv',
    'class':'myClass',
    'style':'cursor:pointer;font-weight:bold;',
    'html':'<span>For HTML</span>',
    'click':function(){ alert(this.id) },
    'mouseenter':function(){ $(this).css('color', 'red'); },
    'mouseleave':function(){ $(this).css('color', 'black'); }
}).appendTo('body');

DEMO.

Mais lorsque vous traitez avec beaucoup d'éléments dynamiques, vous devez éviter d'ajouter un événement handlersdans un élément particulier, à la place, vous devez utiliser un gestionnaire d'événements délégué, comme

$(document).on('click', '.myClass', function(){
    alert(this.innerHTML);
});

var i=1;
for(;i<=200;i++){
    $('<div/>', {
        'class':'myClass',
        'html':'<span>Element'+i+'</span>'
    }).appendTo('body');
}

DEMO.

Donc, si vous créez et ajoutez des centaines d'éléments avec la même classe, c'est-à-dire ( myClass), alors moins de mémoire sera consommée pour la gestion des événements, car un seul gestionnaire sera là pour faire le travail pour tous les éléments insérés dynamiquement.

Mise à jour: puisque nous pouvons utiliser l'approche suivante pour créer un élément dynamique

$('<input/>', {
    'type': 'Text',
    'value':'Some Text',
    'size': '30'
}).appendTo("body");

Mais l' sizeattribut ne peut pas être défini en utilisant cette approche en utilisant jQuery-1.8.0ou plus tard et voici un ancien rapport de bogue , regardez cet exemple en utilisant jQuery-1.7.2qui montre que l' sizeattribut est défini en 30utilisant l'exemple ci-dessus mais en utilisant la même approche, nous ne pouvons pas définir d' sizeattribut en utilisant jQuery-1.8.3, ici est un violon qui ne travaille pas . Donc, pour définir l' sizeattribut, nous pouvons utiliser l'approche suivante

$('<input/>', {
    'type': 'Text',
    'value':'Some Text',
    attr: { size: "30" }
}).appendTo("body");

Ou celui-ci

$('<input/>', {
    'type': 'Text',
    'value':'Some Text',
    prop: { size: "30" }
}).appendTo("body");

Nous pouvons passer attr/propcomme un objet enfant mais il fonctionne dans les jQuery-1.8.0 and laterversions vérifier cet exemple , mais il ne fonctionnera pas dans jQuery-1.7.2 or earlier(non testé dans toutes les versions antérieures).

BTW, extrait du jQueryrapport de bogue

Il existe plusieurs solutions. La première consiste à ne pas l'utiliser du tout, car cela ne vous fait pas économiser d'espace et cela améliore la clarté du code:

Ils ont conseillé d'utiliser l'approche suivante ( fonctionne également dans les versions antérieures , testé dans 1.6.4)

$('<input/>')
.attr( { type:'text', size:50, autofocus:1 } )
.val("Some text").appendTo("body");

Il est donc préférable d'utiliser cette approche, l'OMI. Cette mise à jour est effectuée après avoir lu / trouvé cette réponse et dans cette réponse montre que si vous utilisez à la 'Size'(capital S)place, 'size'cela fonctionnera bien , même dansversion-2.0.2

$('<input>', {
    'type' : 'text',
    'Size' : '50', // size won't work
    'autofocus' : 'true'
}).appendTo('body');

Lisez également à propos de prop , car il y a une différence Attributes vs. Properties, elle varie selon les versions.

L'Alpha
la source
Quel type de sintax est ce $ ('<div />', {.........}), je l'ai cherché et j'en ai trouvé un similaire en utilisant $ ('<div>) .attr ( {......})?
Rafael Ruiz Tabares
@RafaelRuizTabares, en $('<div>', {...})vous passez un objet qui contient tous les attributs et en $('<div>').attr({...})vous créez un élément sans aucun attribut mais en définissant les attributs en utilisant la attr()méthode plus tard.
L'Alpha
@TheAlpha où puis-je trouver des informations sur ce que je peux écrire à l'intérieur {}? Parce que je vois que ce sont des attributs et des événements mais pour <div> vous utilisez aussi du HTML. Merci!
Rafael Ruiz Tabares
Le jQuery.comsite Web de recherche pourrait être utile @RafaelRuizTabares, ou google :-)
L'Alpha
2
C'est de loin le moyen le plus propre et le plus lisible! Probablement pas la voie rapide mais certainement moins sujette aux erreurs lors de l'ajout de chaînes. Merci @TheAlpha
Ares
37

En fait, si vous le faites $('<div>'), jQuery utilisera également document.createElement().

(Jetez un coup d'œil à la ligne 117 ).

Il y a un surcoût d'appel de fonction, mais à moins que les performances ne soient critiques (vous créez des centaines [des milliers] d'éléments), il n'y a pas beaucoup de raisons de revenir au DOM ordinaire .

La simple création d'éléments pour une nouvelle page Web est probablement un cas dans lequel vous vous en tiendrez le mieux à la manière de faire jQuery .

edwin
la source
20

Si vous avez beaucoup de contenu HTML (plus qu'une simple div), vous pouvez envisager de construire le HTML dans la page dans un conteneur caché, puis de le mettre à jour et de le rendre visible en cas de besoin. De cette façon, une grande partie de votre balisage peut être pré-analysée par le navigateur et éviter d'être embourbé par JavaScript lors de son appel. J'espère que cela t'aides!

Collin Allen
la source
Merci pour le conseil. J'ai déjà utilisé cette approche, mais dans ce cas particulier, je souhaite spécifiquement savoir comment créer des éléments.
Darko Z
20

Ce n'est pas la bonne réponse à la question mais je voudrais quand même partager ceci ...

Utiliser simplement document.createElement('div')et sauter JQuery améliorera considérablement les performances lorsque vous souhaitez créer de nombreux éléments à la volée et les ajouter au DOM.

Irshad
la source
16

Je pense que vous utilisez la meilleure méthode, bien que vous puissiez l'optimiser pour:

 $("<div/>");
tvanfosson
la source
11

Vous n'avez pas besoin des performances brutes d'une opération que vous effectuerez extrêmement rarement du point de vue du CPU.

yfeldblum
la source
Cela dépend de la fréquence à laquelle vous le faites.
Rich Bradshaw
8
L'OP crée une fenêtre contextuelle modale . Cette opération n'est pas répétée des milliers de fois par seconde. Au lieu de cela, il est répété peut-être une fois toutes les quelques secondes, au maximum. L'utilisation de la jQuery(html :: String)méthode est parfaitement bien. Sauf si la situation est extrêmement inhabituelle, il est peu probable que l'on obtienne de meilleures performances perçues . Passez l'énergie d'optimisation sur les cas qui pourraient l'utiliser. De plus, jQuery est optimisé pour la vitesse de plusieurs façons. Faites des choses sensées avec lui, et faites confiance mais vérifiez-le pour être rapide.
yfeldblum
9

Vous devez comprendre que la signification des performances de création d'éléments n'est pas pertinente dans le contexte de l'utilisation de jQuery en premier lieu.

Gardez à l'esprit qu'il n'y a pas de véritable objectif de créer un élément à moins que vous ne l'utilisiez réellement.

Vous pouvez être tenté de tester les performances de quelque chose comme $(document.createElement('div'))vs $('<div>')et d'obtenir de grands gains de performances en utilisant, $(document.createElement('div'))mais ce n'est qu'un élément qui n'est pas encore dans le DOM.

Cependant, à la fin de la journée, vous voudrez quand même utiliser l'élément afin que le vrai test devrait inclure f.ex. .ajouter à();

Voyons si vous testez les éléments suivants les uns contre les autres:

var e = $(document.createElement('div')).appendTo('#target');
var e = $('<div>').appendTo('#target');
var e = $('<div></div>').appendTo('#target');
var e = $('<div/>').appendTo('#target');

Vous remarquerez que les résultats varieront. Parfois, une façon est plus performante que l'autre. Et ce n'est que parce que la quantité de tâches en arrière-plan sur votre ordinateur change avec le temps.

Testez-vous ici

Donc, à la fin de la journée, vous voulez choisir la manière la plus petite et la plus lisible de créer un élément. De cette façon, au moins, vos fichiers de script seront les plus petits possibles. Probablement un facteur plus important sur le point des performances que la façon de créer un élément avant de l'utiliser dans le DOM.

Jani Hyytiäinen
la source
Je sais que c'est vieux, mais il n'y a pas besoin de jQuery dans le premier exemple:document.getElementById('target).appendChild(document.createElement('div'));
hisdrewness
7

Un point est qu'il peut être plus facile de faire:

$("<div class=foo id=bar style='color:white;bgcolor:blue;font-size:12pt'></div>")

Ensuite, faites tout cela avec des appels jquery.

Tobiah
la source
3

J'utilise jquery.min v2.0.3. Il est préférable pour moi d'utiliser les éléments suivants:

var select = jQuery("#selecter");
jQuery("`<option/>`",{value: someValue, text: someText}).appendTo(select);

comme suit:

var select = jQuery("#selecter");
jQuery(document.createElement('option')).prop({value: someValue, text: someText}).appendTo(select);

Le temps de traitement du premier code est bien inférieur à celui du second code.

Marcel GJS
la source