Armadilha de design de modelo de Angularjs

O que são ligações?

Cada {{bind}} é analisado internamente pelo angular que cria uma $ watch expression que é usada pelo escopo no $ digest loop para atualizar a view e isso é uma “operação simples”. Da mesma forma, sempre que você criar sua própria expressão $ watch no controlador ou diretiva e sempre que você fizer algo caro, o navegador precisará de mais tempo para atualizar a visualização porque lembre-se de uma operação síncrona e como temos apenas um thread no navegador a invocação de outras coisas é completamente bloqueado porque precisa terminar a invocação anterior.

O que você deve evitar ao usar eventos de escopo ($ emit, $ broadcast)?

Você não deve disparar eventos de escopo dentro de seu $ watcher porque as ligações serão pausadas.
Mesmo se você disparar o evento $ emit (up tree) ou $ broadcast (down tree) fora de $ watcher, isso não impedirá que o loop de resumo seja mais rápido porque cria outro loop de passagem e se esse escopo $ emit ou $ broadcast for caro, ele pause o resumo porque novamente sua operação síncrona.

E quanto a $ watchers, $ digest?

$ watchers são disparados em ordem decrescente e todos os seus $ watchers personalizados serão invocados após a vinculação do template (observadores de template lembram-se das expressões {{bind}}) que é a parte boa, mas angular usa um loop de passagem de profundidade em que não verifica se o escopo pai já está $ vigiado, em vez do loop do observador $ do gatilho novamente nesse escopo pai.

Esta é a razão pela qual você não pode fazer o:

$scope.value = 1;
$scope
.$watch(‘value’, function(){
$scope
.value +=1;
});

Você obtém a mensagem “{0} $ digest () iterations found. Abortando! Observadores disparados nas últimas 5 iterações: {1} ”;

O que significa que cada escopo pai é verificado incorretamente pelo menos duas vezes em vez da verificação suja em tempo real por escopo. A questão é: isso é feito intencionalmente ou acidentalmente? É intencionalmente, então, na minha opinião, um projeto ruim porque chegamos ao fato de que esta é uma operação síncrona. Porque cada vez que isso acontece, a visualização de atualização angular está causando um evento de mutação DOMTree.

E quanto ao scope. $ Apply?

Que escopo de gatilhos $ se aplicam?
Operações assíncronas.
Cada evento assíncrono nativo, por exemplo. (ng-clique, ng-mousedown). Diretivas integradas, por exemplo, ng-model, ng-options, Serviços, por exemplo, $ http, $ timeout, $ interval, $ location, $ q, $ browser.defer, scope. $ EvalAsync

Por que isso é ruim?

Em grandes aplicativos angularjs (150k loc de código), o tempo de compilação está crescendo proporcionalmente com sua árvore de escopo. Como você pode ver na imagem do gráfico o tempo total do Scope. $ Aplicar 1,63s que é realmente muito. A razão para isso é que a estrutura em árvore é muito grande e contém muitos dados. Quando você tem uma estrutura complexa que contém muitos dados, leva tempo para atualizar uma visualização da interface do usuário.
Porque cada Scope. $ Apply executa a travessia da árvore do escopo do escopo raiz ao escopo filho mais profundo. E o número de ligações ao modelo é proporcional ao crescimento do tempo para atualizar a visualização porque é uma operação síncrona.
E se você tem um aplicativo que usa fonte de eventos para entregar dados ao cliente e se vários eventos estão entregando dados ao seu navegador ao mesmo tempo, isso causa vários loops de resumo que são novamente uma operação síncrona.

Se você me perguntar agora, eu sugiro que você use o angular com uma grande estrutura de aplicativo cliente?

Não, eu não sugiro que você use. Mesmo que você decuplique tudo e use amd para carregar todas as coisas, isso não o ajudará a resolver o problema por causa do loop de resumo.!