¿Cuándo favorecer ng-if vs. ng-show / ng-hide?

Respuestas:

703

Depende de su caso de uso, pero para resumir la diferencia:

  1. ng-ifeliminará elementos del DOM. Esto significa que todos sus controladores o cualquier otra cosa asociada a esos elementos se perderán. Por ejemplo, si vincula un controlador de clic a uno de los elementos secundarios, cuando se ng-ifevalúa como falso, ese elemento se eliminará de DOM y su controlador de clic ya no funcionará, incluso después de que ng-ifse evalúe como verdadero y muestre el elemento. Deberá volver a colocar el controlador.
  2. ng-show/ng-hideno elimina los elementos del DOM. Utiliza estilos CSS para ocultar / mostrar elementos (nota: es posible que deba agregar sus propias clases). De esta manera, no se perderán los controladores que se adjuntaron a los niños.
  3. ng-ifcrea un ámbito secundario mientras ng-show/ng-hideno

Los elementos que no están en el DOM tienen menos impacto en el rendimiento y su aplicación web puede parecer más rápida cuando se usa en ng-ifcomparación con ng-show/ng-hide. En mi experiencia, la diferencia es insignificante. Las animaciones son posibles cuando se usan ambos ng-show/ng-hidey ng-if, con ejemplos para ambos en la documentación angular.

En última instancia, la pregunta que debe responder es si puede eliminar el elemento del DOM o no.

markovuksanovic
fuente
19
Puedes usar animaciones CSS3 con ng-if. Consulte el párrafo Animaciones y el ejemplo en los documentos . También con ng-hide/ng-showlos selectores css les gusta :first-childo :nth-childno funcionará correctamente ya que los elementos ocultos también se contarán.
Łukasz Wojciechowski
44
El servicio de animación en angular.dart es relativamente nuevo. Al momento de escribir esto no estaba disponible.
markovuksanovic
44
El primer punto no es un problema si está utilizando directivas (como ng-click) para vincular controladores, como debería ser.
Kevin C.
99
Además, ng-ifcrea un nuevo alcance mientras ng-showno lo hace.
Martin
8
También debe mencionarse que agregar y eliminar elementos del DOM puede generar un alto costo de rendimiento si se realiza con frecuencia.
Kevin C.
130

Vea aquí un CodePen que demuestra la diferencia en cómo funciona ng-if / ng-show, DOM-wise.

@markovuksanovic ha respondido bien a la pregunta. Pero lo hice desde otra perspectiva: siempre usaría ng-ify sacaría esos elementos del DOM, a menos que:

  1. por alguna razón, necesita que los enlaces de datos y $watch-es en sus elementos permanezcan activos mientras son invisibles. Los formularios pueden ser un buen caso para esto, si desea poder verificar la validez de las entradas que actualmente no están visibles, para determinar si todo el formulario es válido.
  2. Está utilizando una lógica de estado realmente elaborada con controladores de eventos condicionales, como se mencionó anteriormente. Dicho esto , si se encuentra adjuntando y desconectando manualmente los controladores, de modo que está perdiendo un estado importante cuando usa ng-if, pregúntese si ese estado estaría mejor representado en un modelo de datos, y los controladores aplicados condicionalmente por directivas cada vez Se representa el elemento. Dicho de otra manera, la presencia / ausencia de controladores es una forma de datos de estado. Obtenga esos datos del DOM y en un modelo. La presencia / ausencia de los manejadores debe estar determinada por los datos y, por lo tanto, fácil de recrear.

Angular está escrito muy bien. Es rápido, considerando lo que hace. Pero lo que hace es un montón de magia que hace que las cosas difíciles (como el enlace de datos bidireccional) parezcan trivialmente fáciles. Hacer que todas esas cosas se vean fáciles implica una sobrecarga de rendimiento. Es posible que se sorprenda al darse cuenta de cuántas cientos o miles de veces se evalúa una función setter durante el$digest ciclo en un trozo de DOM que nadie está mirando. Y luego te das cuenta de que tienes docenas o cientos de elementos invisibles, todos haciendo lo mismo ...

Los escritorios pueden ser lo suficientemente potentes como para hacer que la mayoría de los problemas de velocidad de ejecución de JS sean discutibles. Pero si está desarrollando para dispositivos móviles, usar ng-if siempre que sea humanamente posible debería ser una obviedad. La velocidad de JS sigue siendo importante en los procesadores móviles. Usar ng-if es una manera muy fácil de obtener una optimización potencialmente significativa a un costo muy, muy bajo.

XML
fuente
66
Muy buena adición a la respuesta anterior. Dado con un buen contexto, que también ayuda a la toma de decisiones. Gracias.
Sean
1
ng-showpuede ser útil cuando tiene, digamos pestañas, cada una con mucho contenido que lleva tiempo procesar. Después de la primera representación, moverse entre pestañas será instantáneo, mientras ng-ifque requeriría una nueva representación, eventos vinculantes, etc. La desventaja, como usted dice, es que crea relojes ejecutándose en segundo plano. Angular necesita desesperadamenteng-ifshowwatch
poshest
53

Por mi experiencia:

1) Si su página tiene una palanca que usa ng-if / ng-show para mostrar / ocultar algo, ng-if causa más demoras en el navegador (más lento). Por ejemplo: si tiene un botón utilizado para alternar entre dos vistas, ng-show parece ser más rápido.

2) ng-if creará / destruirá el alcance cuando se evalúe como verdadero / falso. Si tiene un controlador conectado al ng-if, ese código de controlador se ejecutará cada vez que el ng-if se evalúe como verdadero. Si está utilizando ng-show, el código del controlador solo se ejecuta una vez. Entonces, si tiene un botón que alterna entre varias vistas, usar ng-if y ng-show marcaría una gran diferencia en la forma en que escribe el código de su controlador.

Yi Z
fuente
55
Esa es una gran verdad! ng-if no necesariamente hace que su interfaz sea más rápida. Depende de tus necesidades. En realidad, podría ser al revés si está utilizando una situación incorrecta.
Thiago C. S Ventura
1
Pero según yo, ng-if no se procesa en DOM, por lo que es rápido en comparación con ng-show / hide. estoy equivocado por favor déjame corregir en ese punto.
Pardeep Jain
1
ng-if sería más rápido si se evalúa como falso, ya que, como usted dice, no es necesario insertar nada en el DOM. Pero, si es cierto, tiene una sobrecarga de insertar el elemento, posiblemente bastante complicado, en el DOM.
Mawg dice que reinstalar a Monica
"2) ng-if creará / destruirá el alcance cuando se evalúe como verdadero / falso. Si tiene un controlador conectado al ng-if, ese código de controlador se ejecutará cada vez que"
The Red Pea
35

La respuesta no es simple:

Depende de las máquinas de destino (móvil frente a escritorio), depende de la naturaleza de sus datos, el navegador, el sistema operativo, el hardware en el que se ejecuta ... necesitará realizar una evaluación comparativa si realmente quiere saberlo.

Se trata principalmente de un problema de memoria versus cálculo ... ya que con la mayoría de los problemas de rendimiento, la diferencia puede volverse significativa con elementos repetidos (n) como listas, especialmente cuando están anidados (nxn, o peor) y también qué tipo de cálculos ejecuta dentro de estos elementos :

  • ng-show : si esos elementos opcionales a menudo están presentes (densos), como por ejemplo el 90% del tiempo, puede ser más rápido tenerlos listos y solo mostrarlos / ocultarlos, especialmente si su contenido es barato (solo texto simple, nada para calcular o cargar). Esto consume memoria ya que llena el DOM con elementos ocultos, pero solo mostrar / ocultar algo que ya existe es probable que sea una operación barata para el navegador.

  • ng-if : si, por el contrario, es probable que no se muestren elementos (dispersos), simplemente compílelos y destrúyalos en tiempo real, especialmente si su contenido es costoso (cálculos / ordenados / filtrados, imágenes, imágenes generadas). Esto es ideal para elementos raros o 'a pedido', ahorra memoria en términos de no llenar el DOM pero puede costar una gran cantidad de cómputo (creación / destrucción de elementos) y ancho de banda (obtención de contenido remoto). También depende de cuánto calcule en la vista (filtrado / clasificación) frente a lo que ya tiene en el modelo (datos pre-ordenados / pre-filtrados).

Christophe Roussy
fuente
2
Otras respuestas para hechos técnicos. Este para la sabiduría. ¡Claramente ha creado aplicaciones angulares no triviales, señor! 1
poshest
Este problema va más allá de angular, es un problema fundamental en informática, hay un punto desde el cual un método es más eficiente que el otro. Por lo general, esto se puede encontrar a través de algunas evaluaciones comparativas. Por lo tanto, incluso podría cambiar entre un método y otro dependiendo del recuento de elementos ... Tema similar: math.stackexchange.com/questions/1632739/…
Christophe Roussy
12

Una nota importante:

ngIf (a diferencia de ngShow) generalmente crea ámbitos secundarios que pueden producir resultados inesperados.

Tuve un problema relacionado con esto y pasé MUCHO tiempo para descubrir qué estaba pasando.

(Mi directiva estaba escribiendo los valores de su modelo en el alcance incorrecto).

Entonces, para salvar tu cabello, solo usa ngShow a menos que corras demasiado lento.

La diferencia de rendimiento es apenas notable de todos modos y todavía no estoy seguro de a favor de quién es sin una prueba ...

usuario2173353
fuente
8
El uso $parent.scopevaren enlaces de datos dentro de un ngIf rectificará cosas como problemas de ámbitos secundarios cuando se usa ngIf
meconroy
2
Esto no es del todo cierto (el comentario original de @ user2173353, es decir). Si te apegas a las buenas prácticas, no te meterás en problemas. Esa es una regla bastante básica: "si no hay punto, lo estás haciendo mal". Vea aquí una demostración de cómo funciona: bit.ly/1SPv4wL . Otra gran referencia (ver error # 2): bit.ly/1QfFeWd > (Mi directiva estaba escribiendo sus valores de modelo en el alcance incorrecto). Este es el resultado de no apegarse a la práctica anterior.
piotr.d
1
@ piotr.d Tienes razón, pero eso no es algo en lo que un principiante deba centrarse y hay otra mejor práctica que dice que es mejor dejar las mejoras de rendimiento para el final (especialmente las mejoras de rendimiento que pueden no ser mejoras en la realidad ) He visto a personas en ngIftodas partes creyendo que esto mejorará el rendimiento. Esto simplemente no es cierto y uno no puede decir cuál es el mejor, ngIfo ngShow, sin una prueba o un análisis profundo en el caso particular. Por lo tanto, todavía recomiendo olvidarse de eso ngIf, hasta que uno vea un mal desempeño o sepa lo que está haciendo
user2173353
2
Buen punto. Pero el uso de controllerAs hace que esto no sea un problema. Ver, por ejemplo, la versión de John Papa de controllerAs y vm .
jsruok
4

ng-if en ng-include y en ng-controller tendrá un gran impacto en ng-include no cargará el parcial requerido y no se procesará a menos que el indicador sea verdadero en ng-controller, no cargará el controlador a menos que el indicador sea verdadero, pero el problema es cuando un indicador se vuelve falso en ng-si se eliminará del DOM cuando el indicador se vuelva verdadero, volverá a cargar el DOM en este caso ng-show es mejor, por una vez muestra ng-if es mejor

Saad Ahmed
fuente
4

Si utiliza ng-show or ng-hideel contenido (por ejemplo, miniaturas del servidor) se cargará independientemente del valor de la expresión, pero se mostrará en función del valor de la expresión.

Si usa ng-ifel contenido se cargará solo si la expresión de ng-if se evalúa como verdadera.

Usar ng-if es una buena idea en una situación en la que va a cargar datos o imágenes del servidor y mostrarlos solo según la interacción de los usuarios. De esta forma, la carga de su página no se verá bloqueada por tareas innecesarias intensivas.

appdroid
fuente
Esto es especialmente útil ya que la mayoría de los navegadores cargarán imágenes incluso si el CSS oculta sus contenedores DOM. Por lo general, solo buscan el srcatributo de la imgetiqueta, cuando está presente se carga.
Christophe Roussy