HomeSharpStack
mobile-performance5 min

Otimização de Eventos de Toque em Dispositivos Móveis

Otimização de Eventos de Toque em Dispositivos Móveis

Imagine que seu smartphone é como um restaurante muito ocupado. Cada vez que você toca a tela, é como um cliente levantando a mão. Se o garçom (seu navegador) tiver que verificar cada movimento de mão de todos os clientes constantemente, ele fica sobrecarregado e o serviço fica lento. A otimização de eventos de toque funciona assim: em vez de processar tudo, você ensina o garçom a ser inteligente sobre quando e como responder.

O Problema: Por Que Eventos de Toque Causam Lentidão?

Quando você toca a tela de um celular, o navegador dispara eventos (touchstart, touchmove, touchend). Se seu código responde a cada um desses eventos sem cuidado, acontece algo ruim:

  • O navegador precisa processar centenas de eventos por segundo durante um gesto de deslize
  • Se cada evento atualiza a tela ou faz cálculos pesados, a interface congela
  • A bateria do celular drena rapidamente

É como o garçom respondendo a cada aceno de mão em tempo real — impossível!

Solução 1: Throttling (Limitação de Taxa)

Throttling significa "deixar passar apenas alguns eventos". Em vez de processar todos os 60 eventos de toque por segundo, você processa apenas alguns (talvez 10 ou 20).

// Sem throttling - LENTO
element.addEventListener('touchmove', (event) => {
  updatePosition(event.touches[0].clientX);
});

// Com throttling - RÁPIDO
let lastTime = 0;
const throttleDelay = 50; // milissegundos

element.addEventListener('touchmove', (event) => {
  const now = Date.now();
  if (now - lastTime >= throttleDelay) {
    updatePosition(event.touches[0].clientX);
    lastTime = now;
  }
});

Aqui, o código só atualiza a posição a cada 50 milissegundos, não em cada evento. O usuário não percebe a diferença, mas o celular respira!

Solução 2: Event Delegation (Delegação de Eventos)

Imagine que você tem 100 botões em uma lista. Você poderia adicionar um ouvinte de eventos em cada botão (100 ouvintes), ou adicionar um único ouvinte na lista inteira e deixar ele descobrir qual botão foi tocado.

// Ruim: 100 ouvintes
const buttons = document.querySelectorAll('button');
buttons.forEach(btn => {
  btn.addEventListener('click', handleClick);
});

// Bom: 1 ouvinte
const container = document.querySelector('.button-list');
container.addEventListener('click', (event) => {
  if (event.target.tagName === 'BUTTON') {
    handleClick(event);
  }
});

A segunda abordagem usa menos memória e é mais rápida. É como ter um gerente no restaurante em vez de um garçom para cada cliente!

Solução 3: Passive Event Listeners (Ouvintes Passivos)

Por padrão, o navegador espera que seu código de toque termine antes de permitir o scroll. Isso causa atraso. Você pode dizer ao navegador: "Confie em mim, não vou bloquear o scroll".

// Sem passive - navegador espera seu código
element.addEventListener('touchmove', handleTouch);

// Com passive - navegador não espera
element.addEventListener('touchmove', handleTouch, { passive: true });

Use passive: true quando seu código de toque não chamar preventDefault(). Isso deixa o scroll muito mais suave!

Solução 4: Evitar Trabalho Pesado em Event Handlers

Nunca faça cálculos complexos ou atualizações de DOM dentro de um evento de toque. Use requestAnimationFrame para agendar o trabalho:

// Ruim - bloqueia o evento
element.addEventListener('touchmove', (event) => {
  for (let i = 0; i < 1000000; i++) {
    // cálculo pesado
  }
});

// Bom - agenda para depois
let pendingUpdate = false;
element.addEventListener('touchmove', (event) => {
  if (!pendingUpdate) {
    pendingUpdate = true;
    requestAnimationFrame(() => {
      // cálculo pesado aqui
      pendingUpdate = false;
    });
  }
});

Resumo Prático

Para otimizar eventos de toque:

  1. Use throttling para limitar quantas vezes você processa eventos
  2. Use delegação para reduzir o número de ouvintes
  3. Use passive listeners para melhorar o scroll
  4. Agende trabalho pesado com requestAnimationFrame

Key Takeaways

  • Throttling limita a frequência de processamento de eventos de toque, evitando que o navegador fique sobrecarregado com centenas de eventos por segundo
  • Event delegation reduz o número de ouvintes de eventos usando um único listener em um elemento pai em vez de listeners individuais em muitos elementos filhos
  • Passive event listeners e agendamento de trabalho pesado com requestAnimationFrame mantêm a interface responsiva e o scroll suave

Enjoyed this reading?

SharpStack delivers personalized tech readings every day, calibrated to your skill level. 5 minutes a day to stay sharp.

“Stay sharp. At your pace. Everyday.”