Usando APIs Nativas da Web para Reduzir o Tamanho do Pacote e Melhorar o Desempenho

Refatorando Padrões de Design Comuns do React para APIs Nativas da Web
05/27/2024·Tiago Gimenes

No desenvolvimento web moderno, bibliotecas como React se tornaram a norma para construir interfaces de usuário dinâmicas e interativas. No entanto, confiar pesadamente nessas bibliotecas pode, às vezes, levar a tamanhos maiores de pacote e desempenho reduzido. Ao utilizar APIs nativas da web, podemos realizar padrões de design comuns de maneira mais eficiente, melhorando o desempenho e a compatibilidade geral da web. Neste artigo, exploraremos como usar essas APIs para reduzir nossa dependência de hooks do React, como useState.

Estudo de Caso: O Truque do <input type="checkbox" /> Oculto

Uma técnica muitas vezes negligenciada no desenvolvimento web nativo é o truque do <input type="checkbox" /> oculto. Esse truque, que já existe há algum tempo, oferece uma maneira de controlar o estado da interface do usuário sem depender do JavaScript, reduzindo o tamanho do pacote e potencialmente melhorando o desempenho.

A Abordagem com React

Vamos começar com um exemplo típico em React:

import { useState } from "preact/hooks";

export default function Section() {
const [display, setDisplay] = useState(false);

return (
<div class="p-10 grid place-items-center gap-2">
<button onClick={() => setDisplay(!display)} class="btn">Click Me</button>
{display && <div>Hello!</div>}
</div>
);
}

Neste exemplo, o hook useState e o manipulador onClick são usados para alternar a visibilidade de um pedaço da interface do usuário. Embora essa abordagem seja eficaz, ela envolve JavaScript adicional, o que pode contribuir para um tamanho maior de pacote.

A Abordagem com API Nativa da Web

Agora, vamos refatorar este exemplo para usar apenas APIs nativas da web:

export default function Section() {
return (
<div class="p-10 grid place-items-center gap-2">
<input id="toggle" type="checkbox" class="peer hidden" />
<label for="toggle" class="btn">Click Me</label>
<div class="hidden peer-checked:inline">Hello!</div>
</div>
);
}

Explicação

O que está acontecendo aqui? Substituímos o hook useState por um elemento <input type="checkbox" /> oculto. Aqui está um detalhamento das mudanças:

  1. Checkbox Oculto: Introduzimos um <input type="checkbox" /> com um id e a classe hidden. Este checkbox controlará o estado.
  2. Rótulo para Alternar: O <label for="toggle"> está vinculado ao checkbox usando o atributo for, que alterna o estado do checkbox quando clicado.
  3. Classe Peer: Usando a classe peer do Tailwind CSS, podemos estilizar elementos com base no estado do checkbox. A classe peer-checked:inline faz o <div> aparecer quando o checkbox está marcado.

O resultado final tanto no React quanto na API Nativa da Web é indistinguível para o usuário final, mudando apenas as características de desempenho/compatibilidade da aplicação. Além disso, esse truque pode ser aplicado em gavetas, modais e qualquer outro tipo de interface booleana. Abaixo estão alguns exemplos desse uso:

Mais Exemplos
  1. Gaveta
  2. Modal
  3. Código de Cupom

Estudo de Caso: O Truque Esquecido do <input type="radio" />

Outro elemento HTML poderoso, mas muitas vezes negligenciado, é o <input type="radio" />. Isso pode ser especialmente útil para criar seletores de SKU ou componentes de interface semelhantes. Vamos examinar como podemos refatorar um componente React para usar entradas de rádio nativas.

A Abordagem com React

Primeiro, vejamos um componente React típico para um seletor de SKU:

import { useState } from "preact/hooks";

const options = ["1", "2", "3"];

export default function Section() {
const [selected, setSelected] = useState(0);

return (
<ul class="p-10 flex items-center justify-center gap-2">
{options.map((o, index) => (
<li key={index}>
<button
onClick={() => setSelected(index)}
class={`btn btn-circle ${index === selected ? "btn-primary" : ""}`}
>
{o}
</button>
</li>
))}
</ul>
);
}

Neste exemplo, o hook useState e os manipuladores onClick são usados para gerenciar e atualizar o estado selecionado. Esta abordagem, embora eficaz, envolve JavaScript adicional.

A Abordagem com API Nativa da Web

Agora, vamos refatorar este exemplo para usar elementos <input type="radio" />:

const options = ["1", "2", "3"];

export default function Section() {
return (
<ul class="p-10 flex items-center justify-center gap-2">
{options.map((o, index) => (
<li key={index}>
<input
id={o}
name="options"
type="radio"
class="peer hidden"
defaultChecked={index === 0}
/>
<label for={o} class="btn btn-circle peer-checked:btn-primary">
{o}
</label>
</li>
))}
</ul>
);
}

Explicação

Aqui está um detalhamento de como refatoramos o componente React para usar APIs nativas da web:

  1. Entradas de Rádio: Introduzimos elementos <input type="radio" />, cada um com um id único e o mesmo atributo name. A propriedade name garante que apenas um botão de rádio possa ser selecionado por vez dentro do grupo.
  2. Classe Oculta: A classe hidden oculta os botões de rádio da visualização.
  3. Rótulo para Alternar: O <label for={o}> está vinculado à entrada de rádio correspondente usando o atributo for, tornando o rótulo clicável para alterar o estado do botão de rádio.
  4. Default Checked: Usamos o atributo defaultChecked para definir o botão de rádio inicialmente marcado.
  5. Classe Peer: Com a classe peer do Tailwind CSS, podemos estilizar os rótulos com base no estado das entradas de rádio. A classe peer-checked:btn-primary aplica o estilo btn-primary ao rótulo selecionado.

Benefícios e Desvantagens

Usar as técnicas apresentadas neste artigo pode levar a melhorias significativas no desempenho do seu site. Ao reduzir a quantidade de JavaScript necessário, você diminui os tempos de análise e compilação, melhorando assim o Tempo Total de Bloqueio (TBT). Além disso, adicionar animações e transições se torna mais simples, pois estas podem ser gerenciadas diretamente no DOM, eliminando a necessidade de bibliotecas de terceiros frequentemente necessárias no React.

Outra vantagem desses truques com APIs nativas da web é a compatibilidade aprimorada com navegadores. Como essas técnicas são suportadas por todos os principais navegadores, seu site funcionará de maneira consistente em diferentes plataformas, proporcionando uma experiência perfeita para todos os usuários. Além disso, reduzir a dependência de bibliotecas externas pode simplificar seu projeto e reduzir potenciais vulnerabilidades de segurança, enquanto um melhor desempenho em dispositivos de baixo custo garante que um público mais amplo tenha uma boa experiência de usuário.

No entanto, há algumas compensações a considerar. Uma desvantagem é o potencial aumento no tamanho inicial do DOM, pois todos os estados devem ser representados no DOM. Isso pode levar a um Maior Tempo para Primeiro Conteúdo (FCP), já que o navegador precisa carregar mais conteúdo inicialmente. Além disso, embora as APIs nativas da web sejam ótimas para muitos casos de uso, elas podem não ser adequadas para aplicações altamente interativas, onde o gerenciamento complexo de estado e atualizações frequentes são necessários. Nesses casos, frameworks como React oferecem soluções mais poderosas e flexíveis. Considerações de SEO também entram em jogo, pois você precisa garantir que a visibilidade do conteúdo gerenciada através do DOM ainda seja acessível e indexável pelos mecanismos de busca. Por último, à medida que sua aplicação cresce, manter interações complexas de interface puramente através de APIs nativas da web e CSS pode se tornar desafiador, tornando as abstrações fornecidas pelos frameworks benéficas para gerenciar a complexidade.

Conclusão

Usar APIs nativas da web como <input type="checkbox" /> e <input type="radio" /> pode ajudar a reduzir a dependência do JavaScript, resultando em tamanhos de pacote menores e potencialmente melhor desempenho. Embora essa abordagem tenha suas compensações, ela oferece uma maneira simplificada e eficiente de lidar com padrões comuns de interface do usuário.

Fique atento para mais insights sobre como aproveitar as APIs nativas da web para um processo de desenvolvimento web mais eficiente!