js-logo-badge-512

Ainda me lembro do tempo em usava alerts para encontrar erros em JavaScript. :/

Hoje todo navegador tem sua ferramenta de ajuda ao desenvolvedor. Basta pressionar F12 (pelo menos no Chrome, Firefox e Internet Explorer para Windows) em qualquer página e você já pode “hackear” o HTML, CSS e JavaScript, monitorar o tempo de carregamento total ou de cada artefato pertencente ao site, depurar JavaScript linha a linha e muito mais.

Infelizmente, muitos desenvolvedores ainda estão limitados às técnicas arcaicas de depuração JavaScript que consistem praticamente em tentativa e erro, por exemplo inspecionando valores com a função alert. Alguns avançaram um pouco e usam o console.log.

Veremos a seguir algumas técnicas um tanto menos triviais para obter uma experiências mais agrádavel ao desenvolver e testar páginas web.

Depurando Javascript

No Chrome, navegador desenvolvido pelo Google e meu predileto, você pode facilmente depurar a execução de código JavaScript.

Para isso, basta acessar a aba Source da Ferramenta do Desenvolvedor. Ali é possível abrir qualquer asset como CSS e JavaScript, editá-los, salvá-los e ver o resultado da edição sem recarregar a página.

Nos fontes JavaScript você pode definir breakpoints como em qualquer IDE de desenvolvimento. Quando aquele trecho for executado, a execução será interrompida. Então você pode inspecionar variáveis e avançar a execução linha por linha.

01-breakpoint

Porém, embora a depuração com breakpoints seja uma tremenda mão-na-roda, ela nem sempre é suficiente.

Depuração Avançada

O Chrome disponibiliza através do console uma API de linha de comando que possibilita meios mais avançados para depuração. Vejamos algumas funcionalidades interessantes nos tópicos a seguir.

Monitorando eventos

Breakpoints funcionam bem, pelo menos até precisarmos depurar um caso mais complexo envolvendo eventos de teclado e mouse.

Imagine o cenário onde você está trabalhando em uma tela que outros desenvolvedores enfeitaram com vários scripts que usam eventos como mouse move, mouse up, mouse down, key up, key down, etc. Agora sobrou para você corrigir um bug em algum dos vários eventos.

Breakpoints podem não ser adequados para analisar o comportamento dos scriots, pois interromper a sua execução no meio de um evento acaba alterando o resultado final da execução, afinal outros eventos deixarão de ocorrer ou não acontecerão na sua sequência natural. Colocar logs em todos os eventos não é muito produtivo nem viável em alguns casos.

Para facilitar esta tarefa, a API do Chrome tem a função monitorEvents, que permite ao desenvolvedor listar os eventos que ocorrem em um objeto.

Um exemplo para capturar eventos do mouse na página é:

monitorEvents(document.body, 'mouse');

Após a execução deste comando, qualquer ação do mouse na página vai gerar um log no console.

02-console-monitor-events

Para desativar o monitoramento, execute o método unmonitorEvents com os mesmos argumentos de antes. Exemplo:

unmonitorEvents(document.body, 'mouse');

Listando manipuladores de eventos (listeners) associados a um objeto

Depurar uma página complexa é uma tarefa árdua. Em algumas situações, é quase impossível saber quais eventos estão associados a quais objetos. Uma função interessante da API de comandos do Chrome permite descobrir exatamente isso: getEventListeners.

O exemplo a seguir mostra os listeners associados ao documento:

getEventListeners(document);

03-listeners

Monitorando chamadas a funções

Outro caso onde breakpoints não resolvem é quando funções são executadas várias vezes em sequência. Neste caso, podemos monitorar cada chamada realizada a determinadas funções, inclusive quais argumentos foram passados, através da função monitor da API do Chrome. Basta passar o nome de uma função por parâmetro:

monitor(minhaFuncao);

Isso vai gerar um log para cada execução.

04-monitor

Para deixar de monitorar as chamadas, use a função unmonitor:

unmonitor(minhaFuncao);

Analisando o desempenho da aplicação

Você pode testar o desempenho da execução dos scripts através da aba Profile da ferramenta do desenvolvedor.

Entretanto, para testes mais específicos é interessante poder iniciar e parar a análise de consumo de CPU programaticamente. Isso pode ser feito através das funções profile e profileEnd.

Dessa forma, você pode analisar as execuções inclusive de forma intercalada:

profile("A");
profile("B");
profileEnd("B");
profileEnd("A");

05-profiles

Outros navegadores

Vale lembrar também que várias dessas funcionalidades de depuração não estão limitadas ao Google Chrome. Praticamente todos os navegadores modernos possuem uma API e um console onde você pode manipular a página.

O plugin Firebug tem uma API bem completa para depuração. Mesmo sem plugin, o Firefox disponibiliza uma API nativa. O mesmo vale para o Safari da Apple. Até o Internet Explorer tem vários métodos em sua API.

Já a API do Opera não parece contar com muitos comandos avançados, mas possui diversas utilidades.

Conclusões

Quem trabalha com front-end ou qualquer outra camada de um sistema web pode acabar, cedo ou tarde, tendo que consertar algum JavaScript.

Portanto, é sempre bom acompanhar a evolução das ferramentas de depuração de páginas web. Aprender as funcionalidades um pouco mais avançados certamente irá lhe economizar tempo e desgaste desnecessários.