Búsqueda de sitios web

javascript - ¿Cuándo favorecer ng-if frente a ng-show/ng-hide?


Entiendo que ng-show y ng-hide afectan el conjunto de clases de un elemento y que ng-if controla si un elemento se renderiza como parte del DOM.

¿Existen directrices sobre cuándo elegir ng-if en lugar de ng-show/ng-hide o viceversa?

Respuesta #1

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

  1. ng-if eliminará elementos del DOM. Esto significa que todos tus manejadores o cualquier otra cosa adjunta a esos elementos se perderán. Por ejemplo, si enlazaste un manejador de clic a uno de los elementos hijos, cuando ng-if se evalúe como falso, ese elemento será eliminado del DOM y tu manejador de clic dejará de funcionar, incluso después de que ng-if se evalúe como verdadero y muestre el elemento. Necesitarás volver a adjuntar el manejador.
  2. ng-show/ng-hide no elimina los elementos del DOM. Utiliza estilos CSS para ocultar/mostrar elementos (nota: es posible que necesites agregar tus propias clases). De esta manera, tus manejadores que estaban adjuntos a los hijos no se perderán.
  3. ng-if crea un scope hijo mientras que ng-show/ng-hide no lo hace

Los elementos que no están en el DOM tienen menos impacto en el rendimiento y tu aplicación web podría parecer más rápida al usar ng-if en comparación con ng-show/ng-hide. En mi experiencia, la diferencia es insignificante. Las animaciones son posibles al usar tanto ng-show/ng-hide como ng-if, con ejemplos para ambos en la documentación de Angular.

En última instancia, la pregunta que necesitas responder es si puedes eliminar el elemento del DOM o no?

Respuesta #2

Vea aquí un CodePen que demuestra la diferencia en cómo funcionan ng-if/ng-show, en términos de DOM.

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

  1. por alguna razón necesitas que los data-bindings y $watch-es en tus elementos permanezcan activos mientras están invisibles. Los formularios podrían ser un buen caso para esto, si quieres poder comprobar la validez de los campos que no son visibles actualmente, para determinar si todo el formulario es válido.
  2. Estás utilizando una lógica con estado bastante elaborada con manejadores de eventos condicionales, como se mencionó anteriormente. Dicho esto, si te encuentras adjuntando y desadjuntando manejadores manualmente, de manera que pierdes estado importante cuando usas ng-if, pregúntate si ese estado sería mejor representado en un modelo de datos, y los manejadores aplicados condicionalmente por directivas cada vez que se renderiza el elemento. Dicho de otra manera, la presencia/ausencia de manejadores es una forma de datos de estado. Saca esos datos del DOM y colócalos en un modelo. La presencia/ausencia de los manejadores debería determinarse por los datos, y por lo tanto ser fácil de recrear.

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

Las computadoras de escritorio pueden ser lo suficientemente potentes como para que la mayoría de los problemas de velocidad de ejecución de JS sean irrelevantes. Pero si estás desarrollando para móviles, usar ng-if siempre que sea humanamente posible debería ser una obviedad. La velocidad de JS todavía importa en los procesadores móviles. Usar ng-if es una forma muy fácil de obtener una optimización potencialmente significativa a un costo muy, muy bajo.

Respuesta #3

Según mi experiencia:

1) Si tu página tiene un interruptor que usa ng-if/ng-show para mostrar/ocultar algo, ng-if provoca más retraso en el navegador (más lento). Por ejemplo: si tienes un botón usado para alternar entre dos vistas, ng-show parece ser más rápido.

2) ng-if creará/destruirá el scope cuando se evalúe como verdadero/falso. Si tienes un controlador adjunto al ng-if, ese código del controlador se ejecutará cada vez que ng-if se evalúe como verdadero. Si estás usando ng-show, el código del controlador solo se ejecuta una vez. Así que si tienes un botón que alterna entre múltiples vistas, usar ng-if y ng-show haría una gran diferencia en cómo escribes el código de tu controlador.

Respuesta #4

La respuesta no es simple:

Depende de las máquinas objetivo (móvil vs escritorio), depende de la naturaleza de tus datos, del navegador, del sistema operativo, del hardware en el que se ejecuta... necesitarás hacer pruebas de rendimiento si realmente quieres saber.

Es principalmente un problema de memoria vs cálculo ... como 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 (n x n, o peor) y también qué tipo de cálculos realizas dentro de estos elementos:

  • ng-show: Si esos elementos opcionales están presentes con frecuencia (densos), digamos un 90% del tiempo, puede ser más rápido tenerlos listos y solo mostrarlos/ocultarlos, especialmente si su contenido es sencillo (solo texto plano, nada que computar o cargar). Esto consume memoria al llenar el DOM con elementos ocultos, pero solo mostrar/ocultar algo que ya existe probablemente sea una operación económica para el navegador.

  • ng-if: Si, por el contrario, es probable que los elementos no se muestren (escasos), simplemente constrúyelos y destrúyelos en tiempo real, especialmente si su contenido es costoso de obtener (cálculos/ordenados/filtrados, imágenes, imágenes generadas). Esto es ideal para elementos raros o 'bajo demanda', ahorra memoria en términos de no llenar el DOM, pero puede costar mucha computación (creación/destrucción de elementos) y ancho de banda (obtener contenido remoto). También depende de cuánto calcules en la vista (filtrado/ordenamiento) frente a lo que ya tienes en el modelo (datos preordenados/pre-filtrados).

Respuesta #5

Una nota importante:

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

Tuve un problema relacionado con esto y pasé MUCHO tiempo tratando de averiguar qué estaba pasando.

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

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

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

Artículos relacionados