Performance

O que é JMeter?

A utilização de ferramentas para testes de carga e stress é essencial para que possamos testar a performance de nossas aplicações e mantê-las com qualidade mesmo com picos de tráfego.

Com certeza, você já passou por alguma experiência ruim ao acessar um site instável, como por exemplo na hora de comprar um ingresso de um show muito aguardado. Certamente, essa experiência comprometida afetou sua opinião e até mesmo a confiança nestas plataformas que eventualmente passam por alguma degradação de performance. Aqui, mais uma vez, fica evidente a importância de testar a performance da aplicação.

Nginx - Fundamentos
Curso de Nginx - Fundamentos
CONHEÇA O CURSO

Neste artigo, iremos abordar a ferramenta JMeter, uma ferramenta já consolidada e uma das mais conhecidas no mercado para realização de testes de carga e performance. Apesar de ser uma ferramenta muito popular entre os desenvolvedores web, ela tem muitos outros recursos a oferecer.

Mas, antes de adentrarmos no JMeter, precisamos entender um pouco o que vêm a ser os testes de performance.

Testes de performance

Os testes de performance visam testar como nossa aplicação se comporta em geral, principalmente em relação a quantidade de requisições simultâneas. Para isso, submetemos a aplicação a uma avaliação de carga, stress ou resistência para avaliar se os resultados são satisfatórios, visando garantir a qualidade da aplicação.

Realizar esses testes também nos ajuda a avaliar a experiência que o usuário terá na aplicação, onde conseguimos verificar qual o tempo de resposta a cada iteração, por exemplo.

Dentro do teste de performance, temos outros 3 subgrupos. Estes testes nos permitem fazer a análise e monitoramento de resultados, além de fornecerem indicadores importantes. São eles:

Teste de carga
Aqui vemos a quantidade de usuários simultâneos que a aplicação suporta, fazendo os usuários virtuais se comportarem como se fossem usuários reais. Para isso, nos testes de carga, simulamos picos de usuários, sendo feito de pouco em pouco. Também podemos injetar atrasos e paradas nos testes para uma simulação ainda mais realista. Depois, vamos aumentando o volume de usuários gradativamente, para podermos encontrar o limite de capacidade da aplicação.

Teste de resistência
Esse tipo de teste se concentra na estabilidade do sistema ao longo de um período específico, verificando se não há problemas de capacidade de recursos. Entre estes problemas em recursos a serem considerados, podemos citar vazamentos de memória e conexões com banco de dados.

Teste de stress
No teste de stress, geralmente colocamos inicialmente a capacidade máxima que a aplicação pode suportar. Após, é disparada uma grande carga contra a aplicação, onde se tem o objetivo de determinar a capacidade de recuperação e estabilidade do sistema.

É nesses tipos de testes que o JMeter vem para nos ajudar.

JMeter - Fundamentos
Curso de JMeter - Fundamentos
CONHEÇA O CURSO

JMeter

JMeter é uma aplicação gratuita, open source, multiplataforma e escrita em Java, sendo um projeto da Apache Software Foundation. Ela foi desenvolvida inicialmente para testes em aplicações web, mas hoje é possível o utilizar para testes em recursos variados, como banco de dados, servidores de e-mail, requisições HTTP, FTP, TCP, SOAP e outros.

Com o JMeter, você consegue realizar os testes de performance, carga e stress que vimos acima, tornando possível mensurar performance de uma aplicação web.

Em uma aplicação web, por exemplo, você consegue gravar todas as requisições que um usuário faria, simulando ações corriqueiras dentro da aplicação. Essas ações ficam gravadas no JMeter, em uma estrutura conhecida como “grupo de teste”. Após a gravação destas ações, o JMeter possibilita disparar lotes simultâneos e numerosos destas ações, simulando um grupo de usuários. No final, a resposta do servidor para cada solicitação feita é coletada e, com base nessas respostas, as estatísticas são calculadas e as métricas de performance são geradas. O objetivo do JMeter é simular cenários de testes mais reais possíveis.

Se você se interessou pelo JMeter, temos um curso específico dele, onde além de poder conhecê-lo um pouco mais, você ainda poderá vê-lo na prática. Te esperamos lá 🙂

HTTP/2: o que você deve saber?

O protocolo HTTP é um protocolo importante, já que ele é a base da internet e das aplicações web na maneira que conhecemos hoje. E, como a maioria das tecnologias que são extensamente utilizadas, ele evoluiu. Sendo assim, temos uma nova versão do HTTP: o HTTP/2. Antes de tudo, caso não conheça o protocolo HTTP, sugerimos a leitura do artigo “O que é HTTP, Request, GET, POST, Response, 200, 404?”., onde os princípios básicos do protocolo HTTP são abordados. Mas, de forma bem resumida, o HTTP é um protocolo de transferência de arquivos e dados, que vão de um servidor até o cliente (navegador) que solicita estes arquivos e dados.

HTTP - Fundamentos
Curso de HTTP - Fundamentos
CONHEÇA O CURSO

O protocolo HTTP/2

Já de início, devemos ressaltar que o HTTP/2 não muda a semântica do HTTP/1: tudo continua da mesma forma que já conhecemos, com seus verbos e status HTTP. O HTTP/2 foi desenvolvido para resolver alguns problemas que existiam na versão 1.1, principalmente com relação à performance. A maior parte das mudanças dizem respeito à forma que os recursos são transportados entre o cliente e o servidor, tornando esse processo muito mais performático, mesmo em cenários com múltiplas requisições simultâneas.

O HTTP/2 implementa um formato de entrega mais eficiente, acelerando o carregamento das páginas e elementos de uma aplicação web. Este é a principal vantagem que temos na utilização do HTTP/2. Mas ainda existem outras vantagens interessantes, que serão abordadas a seguir.

Multiplexação de mensagens

No HTTP/1, uma conexão é utilizada para baixar um único arquivo, tornando o processo de download de conteúdo algo sequencial. Ou seja: os recursos serão baixados uns atrás dos outros, até que essa “fila de downloads” acabe. Com isso, se um arquivo é muito grande e o servidor ficar lento no meio do processo de download, a página pode acabar passando por um congelamento. Mas o HTTP/2 implementou a multiplexação de mensagens. Com a multiplexação, o navegador não precisa mais ficar esperando receber um recurso para poder requisitar os recursos seguintes. Com o HTTP/2, o navegador pode solicitar e ter a resposta de vários recursos de forma paralela através de apenas uma conexão.

Server Push

Outra funcionalidade bem interessante é o Server Push. Com o HTTP/1.1 (versão anterior do protocolo), o navegador abria uma conexão para baixar cada item da página, se estivermos considerando a carga de uma página web: era uma conexão para baixar o CSS, outra conexão para baixar o JavaScript, e assim por diante, até que todo conteúdo vinculado à página fosse baixado completamente. Se estivermos falando de uma aplicação web que precisa de muitos recursos para ser renderizada, esse processo pode ser um pouco demorado… Já no HTTP/2, o servidor pode enviar recursos ao cache do navegador antes mesmo que o cliente o solicite! Com isso, é possível disponibilizar recursos (como arquivos JavaScript, CSS, imagens e outros recursos comumente utilizados por uma aplicação web) logo durante a interpretação do HTML.

Compressão de cabeçalho (HPACK)

Toda transferência contém um cabeçalho com diversas informações que descreve o recurso que está sendo transferido. Para reduzir a carga e melhorar o desempenho, o HTTP/2 utiliza um algoritmo chamado HPACK para compressão desse cabeçalho, gerando requisições mais leves e, consequentemente, fazendo com que os recursos sejam carregados mais rapidamente.

Priorização de requisições

O HTTP/1.1 tem dificuldade nesse quesito de priorizar requisições. Uma página web é composta por vários elementos. Estes elementos podem ter prioridades diferentes de carregamento no que diz respeito à carga de um recurso. Por exemplo: se estivermos falando de uma página web, não faz sentido que o CSS seja carregado antes de que o HTML esteja disponível.
O HTTP/2 soluciona este problema, já que é possível definir prioridades para os recursos a serem carregados por uma página web, por exemplo. Isso nos possibilitaria instruir o browser a baixar um arquivo CSS que poderia causar bloqueios no processo de renderização da página, caso fosse baixado tardiamente, com uma ordem de prioridade superior aos demais recursos.Esse tipo de priorização não existe no protocolo HTTP/1.1.

Obrigação na utilização de SSL (HTTPS)

Para adotar o HTTP/2, o uso de SSL se torna obrigatório. Isso em termos práticos quer dizer que todo conteúdo trafegado em conexões HTTP/2 estará criptografado com certificados SSL (HTTPS).

O nível atual de adoção do protocolo HTTP/2

Os principais navegadores (como o Chrome, Firefox, Safari e Edge) já oferecem suporte ao HTTP/2. É necessário que os clientes também suportem o HTTP/2 para que seja possível utilizá-lo. Alguns servidores famosos (como o Apache, Tomcat e Nginx) também já suportam o HTTP 2. Caso queira ver uma lista completa, você pode acessar por este link no GitHub.

Para que você perceba a diferença do HTTP/1.1 e do HTTP/2 na prática, você pode abrir o HTTP 2 – Technology Demo. Lá, existe um exemplo de um download de uma foto composta por 200 pequenas imagens através do protocolo HTTP/1.1 e através do protocolo HTTP/2. Nesse cenário, a melhor performance do protocolo HTTP/2 é explícita.

O que é Debounce e qual sua importância para a performance?

Olá, Web Developers!

Hoje vou falar sobre Debounce e a importância de saber quando usar em nossas aplicações.

Se você nunca usou essa técnica ao lidar com eventos como scroll, resize, mousemove, key*, etc, pode ser que enfrente problemas com seus dados e com a performance da sua aplicação.

JavaScript Básico
Curso de JavaScript Básico
CONHEÇA O CURSO

Um exemplo básico

Imagine que temos um simples input do tipo texto. Nós vamos querer que, conforme o usuário vá escrevendo, alguns valores sejam exibidos como sugestão, assim como quando iniciamos uma busca no Google.

Então, quando o usuário para de escrever, temos que enviar o que ele escreveu para o nosso servidor para poder exibir as sugestões.

No exemplo abaixo, ao invés de fazer uma requisição, eu apenas incrementei um contador para vermos quantas requisições teríamos feito se essa fosse uma aplicação de verdade.

const myInput = document.querySelector('input'),
    mySpan = document.querySelector('span');
let counter = 0;

myInput.addEventListener('input', function(){
    mySpan.innerText = ++counter;
})

Vamos usar o evento “onInput” como exemplo. Se escrevermos “TreinaWeb” nesse input, veja que o contador vai acusar que o evento foi disparado 9 vezes.

Imagine só: apenas para enviar “TreinaWeb” para nosso servidor, teríamos feito 9 requisições se tivéssemos usado um simples evento “onInput” sem nenhum tratamento.

Pode parecer pouco, mas pense quando precisamos escutar outros eventos, como um scroll ou mousemove. Uma simples ação do usuário pode acabar disparando centenas ou até milhares de eventos.

Uma solução melhor é fazer uma verificação para saber se o usuário ainda está escrevendo. Se ele parou de digitar, então podemos enviar nosso texto para o servidor.

É aí que entra o Debounce. Ele permite a execução de uma função apenas se um determinado tempo se passou.

Um tratamento simples

Teste agora o exemplo abaixo com o tratamento para ver a diferença. Ao escrever com uma certa velocidade, o evento só será disparado quando você encerrar a digitação.

Mudamos pouca coisa no código:

const myInput = document.querySelector('input'),
    mySpan = document.querySelector('span');

let counter = 0,
    timer = null; // variavel para armazenar nosso timer

myInput.addEventListener('input', function(){
    // limpamos o timer
    clearTimeout(timer);
    // armazenamos o timer novamente
    timer = setTimeout(function(){
        mySpan.innerText = ++counter;
    }, 500);
})

Veja só o que fizemos:

Nossa função agora é executada dentro de um setTimeout. Estamos passando 500ms, ou seja, nosso código só será executado após meio segundo. Você pode mudar esse valor de acordo com sua necessidade.

Nós guardamos o resultado do setTimeout numa variável que chamamos de timer. Acontece que enquanto o usuário estiver digitando, menos de 500ms se passarão, então o nosso evento input será executado novamente. Veja que logo no começo dele nós limpamos o nosso timer com a função clearTimeout. Isso quer dizer que antes mesmo do nosso código ser executado, nós já cancelamos ele. E aí criamos outro setTimeout.

Caso o usuário pare de digitar, nosso evento onInput não será executado novamente, fazendo com que a linha onde executamos o clearTimeout() não seja executada, permitindo que o nosso código finalmente seja executado.

Bem simples e faz um grande benefício para nossas aplicações. Algumas bibliotecas, como o RxJS, nos fornecem já a opção de debounce para executarmos funções numa quantidade reduzida caso haja a possibilidade delas serem chamadas muitas vezes em um tempo muito curto.

Criando uma função “debounce” para reutilização

Tudo bem que só adicionamos menos de cinco linhas em nosso código para tratar uma função, mas imagine que a gente esteja em um sistema e a gente queira tratar várias funções.

Para isso, é melhor criar uma função que trate o debounce para nós.

const myInput = document.querySelector('input'),
    mySpan = document.querySelector('span');
let counter = 0;

function debounce(func, wait) {
    let timer = null;
    return function() {
        clearTimeout(timer);
        timer = setTimeout(func, wait);
    }
}

myInput.addEventListener('input', debounce(function(){
    mySpan.innerText = ++counter;
}, 500));

No código acima nós simplesmente criamos uma função debounce() que já faz o que conhecemos: tem uma variável “timer” e executa uma função que limpa o timer e executa nossa função após um determinado tempo.

Para essa função debounce() nós passamos a função que queremos executar e o tempo que ela deve esperar para ser executada.

Agora temos o mesmo comportamento e também temos a possibilidade de reutilizar essa função em outros lugares.

JavaScript Intermediário
Curso de JavaScript Intermediário
CONHEÇA O CURSO
JavaScript Avançado
Curso de JavaScript Avançado
CONHEÇA O CURSO

© 2004 - 2019 TreinaWeb Tecnologia LTDA - CNPJ: 06.156.637/0001-58 Av. Paulista, 1765, Conj 71 e 72 - Bela Vista - São Paulo - SP - 01311-200