Quando favorecer ng-if vs. ng-show / ng-hide?

Eu entendo que ng-show e ng-hide afetam a class definida em um elemento e que ng-if controla se um elemento é renderizado como parte do DOM.

Existem orientações sobre como escolher ng-if sobre ng-show / ng-hide ou vice-versa?

   

Depende do seu caso de uso, mas para resumir a diferença:

  1. ng-if removerá elementos do DOM. Isso significa que todos os seus manipuladores ou qualquer outra coisa anexada a esses elementos serão perdidos. Por exemplo, se você vincular um manipulador de clique a um dos elementos filho, quando ng-if false, esse elemento será removido do DOM e seu manipulador de cliques não funcionará mais, mesmo depois de ng-if posteriormente ng-if avaliado como verdadeiro e exibe o elemento. Você precisará reconectar o manipulador.
  2. ng-show/ng-hide não remove os elementos do DOM. Ele usa estilos CSS para ocultar / mostrar elementos (nota: você pode precisar adicionar suas próprias classs). Desta forma, seus manipuladores que foram anexados às crianças não serão perdidos.
  3. ng-if cria um escopo filho enquanto ng-show/ng-hide não

Elementos que não estão no DOM têm menos impacto no desempenho e seu aplicativo da Web pode parecer mais rápido ao usar o ng-if comparado ao ng-show/ng-hide . Na minha experiência, a diferença é insignificante. Animações são possíveis quando se usa tanto ng-show/ng-hide quanto ng-if , com exemplos para ambos na documentação Angular.

Em última análise, a pergunta que você precisa responder é se você pode remover o elemento do DOM ou não?

Veja aqui uma CodePen que demonstra a diferença em como ng-if / ng-show funciona, em termos de DOM.

@markovuksanovic respondeu à pergunta bem. Mas eu vim de outra perspectiva: eu sempre usaria o ng-if e obteria esses elementos do DOM, a menos que:

  1. você, por algum motivo, precisa das ligações de dados e de $watch -es em seus elementos para permanecer ativo enquanto são invisíveis. Formulários podem ser um bom exemplo para isso, se você quiser verificar a validade de inputs que não estão visíveis no momento, para determinar se o formulário inteiro é válido.
  2. Você está usando uma lógica stateful realmente elaborada com manipuladores de events condicionais, como mencionado acima. Dito isto , se você se encontrar manualmente anexando e desanexando manipuladores, de modo que você esteja perdendo um estado importante ao usar o ng-if, pergunte a si mesmo se esse estado seria melhor representado em um modelo de dados e se os manipuladores aplicavam condicionalmente por diretivas sempre o elemento é processado. Em outras palavras, a presença / ausência de manipuladores é uma forma de dados de estado. Obtenha esses dados do DOM e em um modelo. A presença / ausência dos manipuladores deve ser determinada pelos dados e, portanto, fácil de recriar.

Angular está escrito muito bem. É rápido, considerando o que faz. Mas o que isso faz é um monte de mágica que torna as coisas difíceis (como binding de dados bidirecional) parecerem trivialmente fáceis. Fazer todas essas coisas parecerem fáceis envolve alguma sobrecarga de desempenho. Você pode ficar chocado ao perceber quantas centenas ou milhares de vezes uma function setter é avaliada durante o ciclo $digest em um pedaço de DOM que ninguém está olhando. E então você percebe que tem dezenas ou centenas de elementos invisíveis, todos fazendo a mesma coisa …

Os desktops podem, na verdade, ser poderosos o suficiente para tornar a maioria dos problemas de velocidade de execução de JS questionáveis. Mas se você está desenvolvendo para dispositivos móveis, usar ng-se sempre que for humanamente possível, deve ser algo óbvio. A velocidade do JS ainda é importante em processadores móveis. Usar o ng-if é uma maneira muito fácil de obter otimização potencialmente significativa a um custo muito baixo.

Da minha experiência:

1) Se a sua página tem um toggle que usa ng-if / ng-show para mostrar / ocultar algo, ng-se causa mais de um atraso do navegador (mais lento). Por exemplo: se você tem um botão usado para alternar entre duas visões, o ng-show parece ser mais rápido.

2) ng-if irá criar / destruir o escopo quando ele for avaliado como verdadeiro / falso. Se você tiver um controlador conectado ao ng-if, esse código do controlador será executado toda vez que o ng-if for avaliado como true. Se você estiver usando ng-show, o código do controlador será executado apenas uma vez. Então, se você tem um botão que alterna entre múltiplas visualizações, usar ng-if e ng-show faria uma enorme diferença na forma como você escreve o código do seu controlador.

A resposta não é simples:

Depende das máquinas de destino (mobile vs desktop), depende da natureza dos seus dados, do navegador, do sistema operacional, do hardware em que são executados … você precisará fazer um benchmark se realmente quiser saber.

É principalmente um problema de computação vs memory … como com a maioria dos problemas de desempenho a diferença pode se tornar significativa com listas repetidas de elementos (n), especialmente quando aninhadas (nxn, ou pior) e também que tipo de cálculos você executa dentro desses elementos :

  • ng-show : Se esses elementos opcionais estão freqüentemente presentes (densos), como 90% do tempo, pode ser mais rápido tê-los prontos e apenas mostrá-los / escondê-los, especialmente se seu conteúdo é barato (apenas texto simples, nada para calcular ou carregar). Isso consome memory à medida que preenche o DOM com elementos ocultos, mas apenas mostrar / ocultar algo que já existe é provável que seja uma operação barata para o navegador.

  • ng-if : Se, pelo contrário, os elementos não forem mostrados (esparsos), basta construí-los e destruí-los em tempo real, especialmente se o seu conteúdo for caro (computação / ordenada / filtrada, imagens, imagens geradas). Isso é ideal para elementos raros ou “on-demand”, economiza memory em termos de não preencher o DOM, mas pode custar muito computação (criação / destruição de elementos) e largura de banda (obtendo conteúdo remoto). Também depende de quanto você computa na visualização (filtragem / sorting) em relação ao que você já tem no modelo (dados pré-classificados / pré-filtrados).

Uma nota importante:

ngIf (ao contrário de ngShow) geralmente cria escopos filho que podem produzir resultados inesperados.

Eu tive um problema relacionado a isso e passei MUITO tempo para descobrir o que estava acontecendo.

(Minha diretiva estava escrevendo seus valores de modelo para o escopo errado.)

Então, para salvar seu cabelo, use ngShow, a menos que você corra muito devagar.

A diferença de desempenho é dificilmente perceptível de qualquer forma e eu não tenho certeza ainda de quem é favor é sem um teste …

ng-se em ng-include e em ng-controller terá um grande impacto em ng-include não carregará o partial necessário e não processará a menos que o flag seja verdadeiro em ng-controller ele não carregará o controller a menos que flag seja verdade, mas o problema é quando um sinalizador fica falso em ng – se ele for removido do DOM quando o sinalizador voltar verdadeiro, ele recarregará o DOM, neste caso, ng-show é melhor, por uma vez, mostrar ng se for melhor

Se você usar ng-show or ng-hide o conteúdo (por exemplo, thumbnails do servidor) será carregado independentemente do valor da expressão, mas será exibido com base no valor da expressão.

Se você usa ng-if o conteúdo será carregado apenas se a expressão do ng-if for avaliada como verdade.

Usar o ng-if é uma boa ideia em uma situação na qual você irá carregar dados ou imagens do servidor e mostrá-los apenas dependendo da interação dos usuários. Desta forma, o carregamento da sua página não será bloqueado por tarefas intensivas desnecessárias.