2009-05-25 4 views
32

Acabo de escribir una función $(). Bind ('evento') y me preocupa que este tipo de llamada sea muy costosa si jQuery tiene que ejecutar cada elemento en el DOM para vincular este evento.¿Los eventos vinculantes en jQuery son muy caros o muy económicos?

O tal vez, es casi tan eficiente como podría ser un evento. Los documentos jQuery que he leído no dejan esto en claro. Alguna opinion?

Respuesta

71

Hay dos cosas que pueden hacer que su código de enlace de evento sea lento: el selector y el número de enlaces. El más crítico de los dos es el número de enlaces, pero el selector podría afectar su rendimiento inicial.

En cuanto a los selectores, asegúrese de no utilizar selectores de nombre de clase puro como .myclass. Si sabe que la clase myclass siempre estará en un elemento <div>, haga que su selector sea div.myclass, ya que ayudará a jQuery a encontrar los elementos coincidentes más rápidamente. Además, no aproveche jQuery, lo que le permite otorgarle enormes cadenas de selección. Todo lo que puede hacer con los selectores de cadenas también lo puede hacer a través de funciones, y esto es intencional, ya que (marginalmente, es cierto) es más rápido hacerlo de esta manera ya que jQuery no tiene que sentarse para analizar la cadena para averiguar qué usted quiere. Entonces, en lugar de hacer $('#myform input:eq(2)');, puede hacer $('input','#myform').eq(2);. Al especificar un contexto, tampoco estamos haciendo que jQuery mire donde no lo tenga, lo cual es mucho más rápido. More on this here.

En cuanto a la cantidad de enlaces: si tiene una cantidad relativamente mediana de elementos, entonces debería estar bien: cualquier cosa hasta 200, 300 combinaciones de elementos potenciales funcionarán bien en los navegadores modernos. Si tiene más que esto, puede que quiera buscar Delegación de evento.

¿Qué es la delegación de eventos? Esencialmente, al ejecutar código como este:

$('div.test').click(function() { 
    doSomething($(this)); 
}); 

jQuery está haciendo algo como esto detrás de las escenas (un enlace de sucesos para cada elemento coincidente):

$('div.test').each(function() { 
    this.addEventListener('click', function() { 
     doSomething(this); 
    }, false); 
}); 

Esto puede ser ineficaz si tiene una gran cantidad de elementos Con la delegación de eventos, puede reducir la cantidad de enlaces reducidos a uno. ¿Pero cómo? El objeto de evento tiene una propiedad target que le permite saber en qué elemento actuó el evento. Por lo que entonces podría hacer algo como esto:

$(document).click(function(e) { 
    var $target = $(e.target); 
    if($target.is('div.test')) { // the element clicked on is a DIV 
           // with a class of test 
     doSomething($target); 
    } 
}); 

suerte que en realidad no tienen que codificar lo anterior con jQuery. La función live, que se anuncia como una manera fácil de vincular eventos a elementos que aún no existen, es realmente capaz de hacer esto mediante el uso de la delegación y comprobación de eventos en el momento en que se produce una acción si el destino coincide con el selector que se especifica . Esto tiene el efecto secundario, por supuesto, de ser muy útil cuando la velocidad es importante.

¿La moraleja de la historia?Si le preocupa la cantidad de enlaces que su script acaba de reemplazar .bind con .live y asegúrese de tener selectores inteligentes.

Tenga en cuenta, sin embargo, que no todos los eventos son compatibles con .live. Si necesita algo que no es compatible con él, puede verificar el livequery plugin, que es en vivo con esteroides.

+1

esta es una gran respuesta – Jason

+2

Cabe señalar que desde que se agregó 'delegate', es posible que sus scripts sean incluso más rápidos que con' live'. –

+4

He encontrado que .myClass es más rápido que div.myClass: http://jsperf.com/div-test-vs-test –

-1

Básicamente, no vas a hacer nada mejor. Todo lo que hace es llamar a attachEventListener() en cada uno de los elementos seleccionados.

En el tiempo de análisis solo, este método es probablemente más rápido que establecer manejadores de eventos inline en cada elemento.

En general, consideraría que esta es una operación muy económica.