Olá sejam todos muito bem-vindos à continuação da série sobre angular JS meu nome é Rodrigo branas autor do livro angular JS Essentials lançado pela Editora pack Pub e hoje no 16º Episódio a gente vai falar sobre uma coisa que incomoda muita gente que é a performance bom mas onde é que tá o gargalo de performance nas nossas aplicações entre muitos fatores eu vou citar dois dos principais tá primeiro deles é excesso de interação com adom isso quer dizer que e sempre que a gente traz um volume muito grande de informações do nosso backend por meio da nossa iepi e tenta renderizados seja usando no n repeat um NG option você vai ver que quanto mais coisas forem renderizadas mais lento vai ficar para usar essa aplicação por meio de um navegador Tá bom então se você faz NG repeats muito grandes por exemplo você tenta renderizar listas aí de centenas ou até de milhares de elementos tenta reduzir de repente utilizar né uma paginação um infin scroll que até por uma questão de usabilidade vai ficar melhor E aí eu com isso faço né uma redução no número de watchers ativos né e faço com que o meu navegador funcione melhor tá por isso que tanta gente hoje em dia né segue utilizando esse tipo de técnica eh segundo fator ele decorre tá da da forma como ciclo de notificação do angular trabalha isso é conhecido como digest cycle tá bom pessoal e por conta dele tá e associado ao mecanismo de two way data binding eu vou mostrar PR você que pode estar havendo um desperdício de tempo processando coisas desnecessárias Tá bom então as técnicas que a gente vai ver e nesse Episódio falam muito sobre esse assunto tá só pra gente relembrar esse aqui né é um um um um diagrama tá que até você vai encontrar na documentação oficial do angler e que fala né do ciclo de notifica ação então e para alguns tipos de eventos por exemplo um clique um Blur um Focus né usando as diretivas do engler né como NG Click NG Blur NG foxus ou mesmo interações com Campos de entrada como input select Tex area que tenham NG Model tudo isso acaba disparando né Por meio dessa chamada apply o apply basicamente encapsula né aquela execução da Expression junto com uma chamada odig cycle E aí faz com que toda a lista de watchers pessoal diversos tipos de Campos né acabam tendo watchers para saber quando precisam se renderizar tá bom para saber quando precisam se atualizar é se renderizando novamente tá então esse ciclo acontece várias vezes durante o uso da aplicação para dar um exemplo né super trivial sobre isso a gente pode por exemplo criar olha só eh uma interpolação de uma variável chamada test E aí criar um campo de entrada Olha só input type text ngg Model ó teste tá esse é o mínimo Tá bom então você repara que sempre que eu digito alguma coisa ó aqui ao lado eu tenho o resultado então é como se sempre que eu apertasse alguma tecla tá eu disparasse esse ciclo ó eu disparasse esse ciclo no momento em que eu aperto essa tecla tá E aí percorrendo a lista de watchers o angular percebeu tá bom que isso aqui precisava ser renderizado de novo tá ele verificou que o valor mudou e por conta disso tá eu acabo vendo esse comportamento aqui que é o two way data binding tá isso é muito legal isso é muito bonito isso dá produtividade mas isso tem impacto em performance por isso que o angular é é vem sendo criticado mas a boa notícia é que desde a versão 1. 3 a gente tem diversas técnicas disponíveis para controlar para domar esse ciclo e é isso que eu vou tentar mostrar né aqui nesse Episódio Então vamos apagar isso aqui e vamos partir pra prática tá primeira coisa é tenha cuidado com expressions tá bom Principalmente aquelas expressions que fazem chamadas a funções a sempre você viu uma Expression com uma chamada função você já começa né a analisar Puxa mas o que que essa função tá fazendo Exatamente vou te mostrar porquê imagina que agora eu tenha que renderizar aqui uma coluna de preço tá então simplesmente eu venho aqui crio uma coluna chamada preço né Eu tenho esse preço disponível quando eu escolho uma operadora lá operadora pon preço como se fosse o o preço da chamada né tá lá ó 1 2 3 tá bom aí eu até posso aplicar ó um Filter para deixar isso aqui mais bonito né e suponhamos que tenha uma necessidade de aplicar um imposto aqui né então entre né Eh eh dentre diferentes abordagens que a gente poderia seguir uma delas envolve o seguinte criar esse imposto aqui né no escopo vamos supor que seja 20% tá E aí nesse momento as pessoas vão seguir caminhos diferentes algumas podem pensar em fazer o seguinte olha Por simplicidade dentro da própria Expression eu posso fazer uma multiplicação né você sabe disso ó imposto a gente falou bastante sobre isso nos Episódios anteriores Então essa multiplicação vai funcionar tudo certo tá mas deixa eu te mostrar eh qual é o impacto disso claro que uma multiplicação simples você não vai vai perceber grandes degradações na performance mas só para exemplificar eu vou transformar isso até por uma questão de e design de código numa chamada a função calcular imposto Tá bom você deve se deparar com isso aqui constantemente no teu dia a dia de trabalho com angular tá repara só scope pon calcular imposto é igual a uma função que recebe preço tá bom aquele preço que veio né aqui de contato. operadora pon preço e aí eu faço um return desse preço vezes um imposto inclusive esse imposto já que a gente vai usar dentro daquela função não precisa estar no escopo né Ó lá e aí aqui eu posso colocar varra né então fizemos essa simples chamada Tá bom você vê que continua funcionando mas eu queria chamar atenção pro seguinte Olha só vou criar um contador para ver quantas vezes essa função foi invocada tá e a aí nesse momento você vai se assustar veja bem só na inicialização já são 17 vezes tá tô usando aplicação de um jeito bem normal olha só reordenando selecionando registros tá bom buscando mais alguma coisa e aí você vê que passou das 100 invocações E aí você começa a se perguntar Poxa mas invocou 100 vezes uma coisa que só foi usada três então quando eu falo né quando eu falo em desperdício de tempo processando coisas desnecessárias é exatamente a isso que eu me refiro Tá bom então Claro a gente tem que tentar pensar em formas diferentes de executar esse tipo de coisa né então qual que seria uma forma interessante né de abordar esse problema bom tem várias mas uma delas é definir Olha só contato pon operadora ponto por exemplo preço com imposto né ou preço após o imposto calculado né E aí a gente pode optar por no Controller tá bom aqui no Controller na inicialização de repente eu até poderia criar uma função chamada init aqui só pra gente fazer essa mediação Olha só vou inclusive mover esse generate serial aqui que é chamado na inicialização para ficar mais explícito olha só repara que esse generate serial faz a mesma coisa ele percorre um a um os registros aplicando um serial tá então calcular impostos né passando os contatos tá bom bom essa função aqui sem dúvida pode ser reusado eu só vou tirar ela do escopo Já que eu não vou usar mais pela View né então sigo usando essa função ela simplesmente recebe um preço e devolve né o o efeito do Imposto tá E aí vamos começar a criar agora ó calcular impostos é igual a uma função que recebe os contatos e aí percorre esses contatos né Ó lá fazendo a seguinte operação né contato pon operador aí a gente tem que se basear aqui ó nesse Campo que a gente criou contato pon operadora pon preço com imposto né ó preço com imposto vai ser resultante da chamada de calcular imposto em que eu passo o contato pon operadora pon preço n bom feito isso fiz a chamada Eh vamos fazer um teste para ver se deu certo e repara que eu só chamei três vezes repara que quando eu tô operando a aplicação ó eu não sinto nenhuma diferença eu não tô ou seja desperdiçando Olha só tempo processando coisas desnecessárias já processei já tá lá não vai mudar mais né o imposto não muda dinamicamente ele vem né e é do teu backend é aplicado e não muda mais então não há necessidade né de invocar essa função a todo o tempo tá bom então você vê que com e e uma simples modificação a gente já foi capaz Olha só de reduzir o desperdício tá então cuidado né com as expressions cuidado com a forma como elas funcionam tá bom beleza Se você começar a reparar aqui ó eu também tenho dentro do ngf repara que isso aqui é uma interpolação de expressão mas a expressão existe né também por exemplo no ngif no NG show no NG Hide e em outras diretivas tá então esse is contato selecionado se a gente for analisar ele faz um uma operação pon som ou seja ele vê se dentro desse arrei alguém está selecionado se tem alguém retorna true ele vai ser o nosso próximo alvo aqui da análise né então eu vou simplesmente mover esse Counter repara que eu não usei e Nenhuma ferramenta muito rebuscada para isso você pode e deve usar né Você tem o profiler do Chrome eu vou mostrar o angular JS batarang né que também faz um trabalho legal mas aqui eu tô usando só o console para te mostrar que tem muita Olha só oportunidade de melhoria tá vendo pessoal de novo e isso a gente tá falando né e eh de uma aplicação super simples uma aplicação tá mostrando três registros e que não tem lá grandes coisas renderizadas você imagina aí no teu dia a dia na tua tela mais complexa né olha só uma simples operação de poucos segundos já gerou aí 54 chamadas pra função is contato selecionado né bom agora você vai ter que repensar um pouco né Qual é o drawback bom você vai deixar de fazer uma coisa mais fácil o angular ele tem a grande vantagem né o trade databind ele traz essa vantagem de escrever menos código né de fazer uma uma abordagem mais declarativa e não imperativa mas às vezes o imperativo ajuda né Então vamos lá vou tirar esses contat selecionado e vou colocar o seguinte ó repara que não é mais uma chamada agora é rest contato selecionado ou seja esta variável vai ser true false né então ngif vai se basear numa variável true falo não mais de uma chamada função então isso vai fazer com que aquele Dirty checking que ele faz ou seja para ver se o valor mudou seja facilitado bom como é que a gente faz então eu vou usar o próprio clique aqui né no checkbox para disparar ação então NG Click eu vou mandar ele fazer um verificar contato selecionado Ou seja eu não sei se o cara tá selecionando ou desselecionar que agora é diferente não é em toda a notificação agora é só quando clicar volta para cá e vamos mudar o seguinte ó ISO contato selecionado agora não pode mais ser assim é verificar contato ionado E aí eu ao invés de fazer um return eu vou fazer um scope p has contato selecionado que é aquela variável que a gente falou né E que vai impactar aqui ó o ngif tá então rest contato selecionado sempre que eu clicar eu mando verificar quando eu mandar verificar segue executando a mesma regra de Anes só que agora obviamente num ciclo Olha só diferenciado Tá vendo como deu o mesmo efeito mas de um jeito muito mais racional posso mexer na aplicação inteira olha aqui nada muda tá vendo ó só chamei sete vezes que foram exatamente referentes Aos sete cliques que eu dei Ok claro que quando eu fizer o delete aqui ó apagar o contato eu vou ter que invocar de novo aí isso que eu tô falando vai ficar mais imperativo mas é melhor fazer isso do que você ter uma degradação excessiva na performance isso é muito de perceber tá é muito de usar a aplicação e come começar a achar esses momentos em que você pode otimizar ó paguei tudo certo tá bom então e Resumindo tá toma cuidado com as suas expressions com as suas interpolações de expressão com os locais onde você tá invocando funções principalmente se forem complexas quanto mais complexo for mais degradação vai trazer Tá show de bola bom na sequência vamos falar de One Time bind bom da versão 1.
3 paraa frente o angler trouxe uma coisa muito importante e que não sei porque pouca gente usa que é o One Time bind Deixa eu te mostrar uma ferramenta chamada angl JS batarang bom essa ferramenta tá ela pode ser interessante para que você analise alguns aspectos como por exemplo olha só fazendo um refresh aqui quantidade de watchers ativos tempo de execução do ciclo tá tá vendo que eu tenho 36 watchers e o ciclo levou 500 msos bom você repara que esses watchers aos quais ele se refere é isso aqui é um watcher isso aqui é um watcher isso aqui é um watcher isso aqui é um watch então poss fazer o seguinte olha escrevendo dois pontos duas vezes eu digo assim ó eu quero que esse comportamento seja One Time isso quer dizer que depois que eu recebi o valor eu tiro o watcher e o angular Não se preocupa mais com ele repara que quando eu fizer um refresh eu baixei de 36 para 33 e assim eu posso aplicar isso olha só em todas as interpolações de expressão que eu sei que não mudam Né repara que ela só mudaria Se eu tivesse por exemplo realizando uma operação multiplicando um valor que tá mudando num campo né O que não é o caso aqui então repara que de 36 watchers eu baixei para 21 de de de meio segundo né eu baixei para E 0. 210 então repara como a gente consegue obter vantagens melhorias de performance com ações simples né uma delas é o o One Time bind mas Analisa bem né se você pode aplicar se não vai ter nenhum Impacto Tá bom E aí por fim eu vou falar um pouquinho do NG Model options NG Model options vem nesse pacote também do One Time bind e é outra coisa que deve ser utilizada que deve ser explorada repara só nesse input aqui ó eu tenho um critério de busca e sempre que eu digito alguma coisa agora a gente volta aqui para esse ciclo de notificação sempre que eu digito alguma coisa chamo o apply ele passa no ciclo notifica o watcher e dá esse efeito legal que você viu aqui ó eu digito alguma coisa e filtro tá bom bom esse comportamento ele não é legal se eu tiver muito item na lista tá e você vai ver aplicações aí travando se você tiver por exemplo 100 200 300 elementos renderizados com muitas coisas filtros por exemplo e expressions mais complexas e você ficar buscando já que ele vai ter que mudar aquela lista então eu posso dizer o seguinte olha aqui para esse NG Model eu vou mudar eu vou dizer NG Model options E aí vou colocar dentro um objeto algumas diretivas se comportam com objetos como n Class por exemplo primeira coisa é update on por padrão que é o default o padrão dele é esse tá digitou uma letra notificou tá eu posso mudar isso por exemplo para Blur Olha só você concorda que pra maior parte dos casos esse não é o caso Tá mas pra maior parte dos casos o Blur é suficiente Só quando eu saio do campo é que olha só eu interajo com o Esopo e dispara o ciclo de notificação então mudei um pouco a forma como o two databinding se comporta eu domei um pouco esse ciclo tá e em termos de usabilidade não ficou legal eu tenho que digitar e sair né tá Seria equivalente quase apertar um botão né não ficou legal então eu posso complementar esse NG Model options com uma opção chamada D Bounce o de Bounce ele pode funcionar olha só até condensando ó Def e Blur então eu posso dizer assim olha default 500 msos Então espere eu parar de digitar por meio segundo E aí aplique e Blur zero quando eu sair do campo pode disparar tranquilamente tá olha só tô escrevendo aqui quando eu parei ele executou legal né você sabe que antigamente versão zero do angular a gente fazia isso na mão a gente implementava um Filter implementava um serviço para gerar um set time Out para cancelar o time out quando alguém digitar outra letra e agora você tem isso fácil né acessível com basicamente uma diretiva só né E aí se eu sair por exemplo do Campo na mesma hora ó não deu tempo aqui vamos sair do campo rápido ó saí ele já aplicou então você vê que eu consigo configurar um comportamento pro Blur e outro outro comportamento por default né então isso sem dúvida alguma dá um ganho de performance muito grande só que claro deixa para aplicar quando você realmente sentir que fez diferença você tem de repente um uma tela simples com dois Campos você vai botar em Model op Talvez não tenha Impacto Tá quanto mais watchers mais Impacto ele vai ter mais Impacto positivo menos degradação de performance tá bom pessoal bom legal então a gente viu três técnicas legais uma delas é cuidar com expressões sempre que tiverem funções complexas sendo usadas usar o One Time bind sempre que necessário e aplicar energ Model option para mudar a forma como o trade data binding do angular funciona fazendo com que eu economize recursos invocando menos watchers e assim tendo uma aplicação mais saudável mais performática tá bom legal vou ficando por aqui Obrigado por assistir mais uma vez tá E não deixa de lá né no nosso Twitter tá Rodrigo branas lá eu divulgo muita informação de evento artigo interessante vídeo que tá sendo lançado tá bom lá no slide share tem essa apresentação tá Não deixe de assinar nosso canal só assim você fica sabendo né de novidades de novas séries novos episódios e assim também você nos apoia tá bom lá no github e esse código também estará disponível basta acessar github.