Pedi para uma IA gerar uma landing page. Sessenta segundos: layout moderno, tipografia elegante, gradientes, sombras. Visual impecável.
Sessenta segundos. Esse é o tempo que uma IA generativa leva para criar uma landing page completa. Layout moderno, tipografia elegante, hero section com gradiente, cards com sombras suaves, call-to-action pulsante. Visualmente, é impressionante.
Agora rode o Lighthouse. Score: 34. Abra com um screen reader. Experiência: inutilizável. Teste no celular com 3G. Tempo de carregamento: 8 segundos. Tente navegar só com teclado. Resultado: você fica preso no terceiro elemento.
A IA gerou UI. Não gerou UX.
E esse gap — entre "parece bom" e "funciona bem" — é precisamente onde mora a engenharia de front-end. Não a parte que cola componentes. Não a parte que copia layout do Figma. A parte que faz um site carregar em 1.2 segundo numa conexão instável em São Paulo. A parte que permite uma pessoa cega navegar com a mesma eficiência de uma pessoa com visão. A parte que não quebra quando o text falha, quando a API demora, quando o usuário faz exatamente aquilo que ninguém previu.
A narrativa dominante em 2026 é que a IA vai substituir front-end developers. A realidade é o oposto: a IA está revelando que o front-end que sempre importou — acessível, performático, responsivo, resiliente — nunca foi sobre aparência. E esse front-end exige mais engenharia do que nunca.
Se a IA consegue fazer 80% do front-end visual, então os 20% restantes — os que realmente afetam o usuário — representam agora 100% do valor do engenheiro.
Este artigo é sobre esses 20%.
Vamos começar com um experimento que qualquer pessoa pode replicar. Peça a uma IA para gerar uma página de e-commerce com listagem de produtos, filtros, carrinho e checkout. Você vai receber código funcional em minutos. A página vai renderizar. Os botões vão ter hover states. O layout vai ser responsivo (mais ou menos).
Agora aplique os critérios que um front-end engineer aplicaria:
| Critério | IA Gerou | Engenheiro Construiu |
|---|---|---|
| Lighthouse Performance | 34-52 | 92-100 |
| Lighthouse Accessibility | 45-68 | 95-100 |
| LCP (Largest Contentful Paint) | 4.2s | 1.1s |
| CLS (Cumulative Layout Shift) | 0.42 | 0.02 |
| INP (Interaction to Next Paint) | 380ms | 85ms |
| Bundle size (JS) | 847KB | 213KB |
| Imagens otimizadas | Nenhuma | WebP/AVIF com srcset |
| HTML semântico | Divs genéricas | Landmarks + headings hierárquicos |
| Navegação por teclado | Parcialmente quebrada | Completa com focus management |
| Funciona sem JS | Não | Conteúdo base acessível |
Esse não é um cenário hipotético. É o resultado médio que encontramos ao auditar código gerado por IA em projetos reais ao longo de 2025.
O problema não é que a IA gera código ruim. É que a IA gera código ingênuo. Código que funciona no happy path, no navegador do desenvolvedor, com conexão rápida, tela grande, mouse e visão perfeita. Código que não passou pelo crivo de nenhuma restrição real.
E front-end engineering, no fundo, é a arte de trabalhar sob restrições.
De todos os gaps entre IA e engenharia de front-end, acessibilidade é o mais profundo. Não é que a IA gera código inacessível por malícia — é que acessibilidade exige um modelo mental que IA simplesmente não tem: a capacidade de imaginar experiências sensoriais diferentes da visual.
Quando você pede à IA "crie um card de produto", ela gera algo assim:
<!-- IA gera: visualmente correto, semanticamente vazio -->
<div class="card">
<div class="card-image">
<img src="produto.jpg">
</div>
<div class="card-title">Fone Bluetooth XR-500</div>
<div class="card-price">R$ 299,90</div>
<div class="card-button" onclick="addToCart()">
Adicionar ao Carrinho
</div>
</div>
Um engenheiro de front-end gera:
<!-- Engenheiro constrói: visual equivalente, semanticamente rico -->
<article class="card" aria-labelledby="product-xr500-title">
<figure class="card-image">
<img
src="produto.webp"
alt="Fone de ouvido Bluetooth XR-500, cor preta, over-ear"
loading="lazy"
decoding="async"
width="400"
height="300"
>
</figure>
<h3 class="card-title" id="product-xr500-title">
Fone Bluetooth XR-500
</h3>
<p class="card-price">
<span class="sr-only">Preço:</span>
R$ 299,90
</p>
<button
class="card-button"
type="button"
aria-label="Adicionar Fone Bluetooth XR-500 ao carrinho"
>
Adicionar ao Carrinho
</button>
</article>
A diferença visual? Nenhuma. A diferença funcional? Enorme.
No primeiro exemplo, um screen reader lê uma sequência de textos desconectados dentro de divs genéricas. Não há hierarquia. Não há contexto. O "botão" é uma div — não é focável por teclado, não responde a Enter/Space nativamente, não comunica role de botão para tecnologias assistivas. A imagem não tem texto alternativo. O preço não tem contexto semântico.
No segundo exemplo, o screen reader anuncia: "Artigo: Fone Bluetooth XR-500. Imagem: Fone de ouvido Bluetooth XR-500, cor preta, over-ear. Preço: R$ 299,90. Botão: Adicionar Fone Bluetooth XR-500 ao carrinho." Uma experiência completa e navegável.
O relatório WebAIM Million analisa as 1 milhão de home pages mais visitadas da web e, consistentemente, encontra que mais de 96% possuem erros detectáveis de WCAG. A IA foi treinada nesse código. Ela reproduz os mesmos padrões inacessíveis da web em escala.
Existe um ditado na comunidade de acessibilidade: "No ARIA is better than bad ARIA." E a IA tem uma tendência preocupante de gerar ARIA excessivo e incorreto.
<!-- ARIA teatro: parece acessível, piora a experiência -->
<div role="button" aria-label="button" aria-pressed="false"
aria-describedby="btn-desc" tabindex="0">
<span id="btn-desc" aria-hidden="true">Clique aqui</span>
Enviar
</div>
<!-- ARIA correto: mínimo e funcional -->
<button type="submit">Enviar</button>
O primeiro exemplo tem cinco atributos ARIA. O segundo não tem nenhum. O segundo é dramaticamente mais acessível. Por quê? Porque o elemento <button> nativo já comunica role, estado e é focável por teclado sem nenhuma configuração adicional.
A primeira regra de ARIA é: não use ARIA se você pode usar HTML nativo. A IA, treinada em milhões de exemplos onde desenvolvedores usaram ARIA desnecessariamente, reproduz e amplifica esse anti-pattern.
Teste qualquer aplicação gerada por IA com o Tab: você vai encontrar problemas em menos de 30 segundos. Modais que não prendem o foco. Dropdowns que não respondem a Arrow keys. Skip links inexistentes. Focus traps em menus de navegação.
O engenheiro de front-end implementa focus management deliberado:
// Focus trap para modal — padrão que IA raramente implementa corretamente
function trapFocus(modalElement) {
const focusableSelectors = [
'button:not([disabled])',
'a[href]',
'input:not([disabled])',
'select:not([disabled])',
'textarea:not([disabled])',
'[tabindex]:not([tabindex="-1"])'
].join(', ');
const focusableElements = modalElement.querySelectorAll(focusableSelectors);
const firstFocusable = focusableElements[0];
const lastFocusable = focusableElements[focusableElements.length - 1];
// Move foco para o modal ao abrir
firstFocusable.focus();
modalElement.addEventListener('keydown', (e) => {
if (e.key === 'Escape') {
closeModal();
// Retorna foco ao elemento que abriu o modal
triggerElement.focus();
return;
}
if (e.key !== 'Tab') return;
if (e.shiftKey) {
if (document.activeElement === firstFocusable) {
e.preventDefault();
lastFocusable.focus();
}
} else {
if (document.activeElement === lastFocusable) {
e.preventDefault();
firstFocusable.focus();
}
}
});
}
Esse é o tipo de código que nunca aparece em screenshots, nunca impressiona em demos, mas define se 15% da população mundial pode ou não usar sua aplicação.
WCAG 2.1 nível AA não é aspiracional. É o padrão legal em muitos países e o mínimo ético em todos. Na prática, significa:
| Critério | Requisito | IA Costuma Falhar? |
|---|---|---|
| 1.1.1 Non-text Content | Todas as imagens precisam de alt text significativo | Sim — gera alt vazio ou genérico |
| 1.3.1 Info and Relationships | Estrutura semântica com headings hierárquicos | Sim — usa divs com classes visuais |
| 1.4.3 Contrast | Ratio mínimo 4.5:1 para texto normal | Às vezes — depende do tema |
| 2.1.1 Keyboard | Todo conteúdo operável por teclado | Sim — onclick em divs, sem tabindex |
| 2.4.3 Focus Order | Ordem lógica de navegação | Sim — focus order segue DOM, que é aleatório |
| 2.4.7 Focus Visible | Indicador visual de foco | Sim — remove outline "porque é feio" |
| 4.1.2 Name, Role, Value | Componentes custom comunicam estado | Sim — falta ARIA em componentes complexos |
Ferramentas automatizadas como axe-core detectam aproximadamente 30-40% dos problemas de acessibilidade. Os outros 60-70% exigem teste manual: navegar com screen reader, testar só com teclado, verificar se o conteúdo faz sentido linearizado, validar que estados interativos são comunicados.
// Setup mínimo de teste automatizado com jest-axe
import { axe, toHaveNoViolations } from 'jest-axe';
expect.extend(toHaveNoViolations);
test('ProductCard não deve ter violações de acessibilidade', async () => {
const { container } = render(<ProductCard product={mockProduct} />);
const results = await axe(container);
expect(results).toHaveNoViolations();
});
Automatize o que pode. Mas nunca confie que automatizado é suficiente. Acessibilidade é sobre experiência humana — e experiência precisa ser testada por humanos.
Performance não é otimização. Performance é arquitetura. Essa distinção é crucial porque a IA trata performance como algo que se adiciona depois — um passo de otimização no final. Engenheiros de front-end sabem que performance é uma decisão de design que permeia todas as camadas, do primeiro byte ao último pixel.
O Google usa três métricas como proxy de experiência do usuário, e desde 2024 elas impactam diretamente ranking de busca:
LCP (Largest Contentful Paint) — Quanto tempo até o maior elemento visível carregar?
<!-- IA gera: hero image sem otimização -->
<img src="hero-4k.png" class="hero-image">
<!-- Engenheiro constrói: loading strategy completa -->
<picture>
<source
srcset="hero-400.avif 400w, hero-800.avif 800w, hero-1200.avif 1200w"
sizes="100vw"
type="image/avif"
>
<source
srcset="hero-400.webp 400w, hero-800.webp 800w, hero-1200.webp 1200w"
sizes="100vw"
type="image/webp"
>
<img
src="hero-800.jpg"
alt="Descrição significativa do hero"
fetchpriority="high"
decoding="async"
width="1200"
height="630"
>
</picture>
Um PNG de 4K tem em média 2-4MB. O equivalente em AVIF com srcset responsivo: 40-120KB dependendo da viewport. A diferença em LCP pode ser de 5 segundos.
CLS (Cumulative Layout Shift) — Quanto o layout se move inesperadamente?
/* IA gera: imagens sem dimensões reservadas */
.card-image img {
width: 100%;
height: auto; /* CLS garantido quando a imagem carregar */
}
/* Engenheiro constrói: espaço reservado com aspect-ratio */
.card-image {
aspect-ratio: 4 / 3;
overflow: hidden;
background: var(--color-placeholder, #e8e8e8);
}
.card-image img {
width: 100%;
height: 100%;
object-fit: cover;
}
CLS é a métrica mais traiçoeira. O usuário está prestes a clicar em "Adicionar ao Carrinho" e o layout pula porque uma imagem acima carregou sem dimensões reservadas. O clique vai parar no "Remover item". Pesquisas indicam que layout shift frustrante é uma das principais causas de abandono em mobile.
INP (Interaction to Next Paint) — Quanto tempo entre a ação do usuário e o feedback visual?
// IA gera: handler síncrono que bloqueia a thread
function handleFilterChange(filters) {
const filtered = products.filter(p =>
matchesAllFilters(p, filters) // Operação pesada no main thread
);
setProducts(filtered);
}
// Engenheiro constrói: yield para o browser entre operações
async function handleFilterChange(filters) {
// Feedback visual imediato
setIsFiltering(true);
// Yield para o browser pintar o estado de loading
await scheduler.yield();
// Processar em chunks para não bloquear interações
const filtered = await filterInChunks(products, filters, 50);
setProducts(filtered);
setIsFiltering(false);
}
O HTTP Archive mostra que a página mediana transfere centenas de KB de text comprimido. Descomprimido, isso frequentemente passa de 1MB. E cada KB de text tem custo triplo: download, parse e execução.
A IA tende a importar bibliotecas inteiras para usar uma função:
// IA gera: 72KB para formatar uma data
import moment from 'moment';
const formatted = moment(date).format('DD/MM/YYYY');
// Engenheiro usa: 0KB — API nativa
const formatted = new Intl.DateTimeFormat('pt-BR').format(date);
// IA gera: 35KB para um debounce
import { debounce } from 'lodash';
// Engenheiro escreve: 15 linhas, 0KB de dependência
function debounce(fn, delay) {
let timeoutId;
return function (...args) {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => fn.apply(this, args), delay);
};
}
Um front-end engineer faz bundle analysis regularmente. Sabe quanto cada dependência custa. Questiona cada import. Implementa code splitting por rota. Configura tree shaking. Sabe a diferença entre import { debounce } from 'lodash' (importa tudo) e import debounce from 'lodash/debounce' (importa só o módulo).
A escolha entre server-side rendering, client-side rendering e streaming SSR não é uma configuração que a IA decide bem. É uma decisão de arquitetura que depende do perfil do conteúdo, do público e das restrições de infraestrutura.
| Estratégia | Melhor Para | Trade-off |
|---|---|---|
| SSR | Conteúdo estático/SEO, landing pages | Maior TTFB, carga no servidor |
| CSR | Apps interativos tipo dashboard | TTI alto, SEO ruim sem hidratação |
| Streaming SSR | Apps híbridos com React 18+ / Next.js | Complexidade, mas melhor TTFB + TTI |
| SSG | Blogs, documentação, catálogos | Build time, conteúdo "velho" até rebuild |
| ISR | E-commerce, conteúdo semi-dinâmico | Complexidade de invalidação |
// Streaming SSR com React Suspense — padrão que IA raramente sugere corretamente
export default function ProductPage({ productId }) {
return (
<main>
{/* Conteúdo crítico: renderizado no servidor imediatamente */}
<Suspense fallback={<ProductSkeleton />}>
<ProductDetails id={productId} />
</Suspense>
{/* Conteúdo secundário: streamed depois */}
<Suspense fallback={<ReviewsSkeleton />}>
<ProductReviews id={productId} />
</Suspense>
{/* Conteúdo terciário: carregado no cliente */}
<Suspense fallback={<RecommendationsSkeleton />}>
<LazyRecommendations id={productId} />
</Suspense>
</main>
);
}
Cada Suspense boundary é uma decisão de prioridade. O que o usuário precisa ver primeiro? O que pode esperar? O que pode carregar só quando visível? Essas são decisões de produto que exigem entendimento do usuário, não apenas do código.
Sr Frontend Engineer
Sou software engineer com mais de 10 anos de experiência construindo plataformas B2B e B2C para empresas de fintech, saúde e educação. Pós-graduado em arquitetura de software e soluções, conecto visão técnica com resultados de negócio para entregar experiências que fazem sentido para as pessoas. Também mentoro devs e criadores em turmas ao vivo, podcasts e iniciativas de comunidade focadas em tecnologia inclusiva.
Produtos gratuitos e pagos para transformar ideias em uma base que você consegue executar.
13 produtos disponíveisContinue explorando tópicos similares

Um guia aprofundado sobre como a Fase 1 do Pos Tech FIAP forma engenheiros(as) front-end completos, unindo JavaScript avançado, TypeScript robusto, Design Systems, Next.js e fundamentos de arquitetura, performance e memória — da teoria à aplicação em produção.

Um guia prático e organizado para quem quer começar no Front-End do jeito certo. Neste artigo, você aprende os fundamentos essenciais, a ordem correta de estudos, projetos práticos e como montar a base do seu portfólio como desenvolvedor front-end iniciante.

React components misturando UI + business logic = nightmare. Clean Architecture separa domain logic, deixando React apenas como presentation layer facilmente substituivel.
Checklist prático para validar segurança, custos, avaliações e observabilidade antes de colocar seu app com IA em produção.
Templates testados em produção, usados por desenvolvedores. Economize semanas de setup no seu próximo projeto.

"Funciona no meu iPhone" não é responsividade. Responsividade real significa funcionar em qualquer viewport, qualquer densidade de pixel, qualquer método de input, qualquer condição de rede.
/* IA gera: breakpoints rígidos */
h1 { font-size: 24px; }
@media (min-width: 768px) { h1 { font-size: 32px; } }
@media (min-width: 1024px) { h1 { font-size: 48px; } }
/* Engenheiro constrói: escala fluida sem breakpoints */
h1 {
font-size: clamp(1.5rem, 1rem + 2.5vw, 3rem);
line-height: clamp(1.8rem, 1.3rem + 2.8vw, 3.4rem);
}
/* Sistema de spacing fluido */
:root {
--space-s: clamp(0.75rem, 0.65rem + 0.5vw, 1rem);
--space-m: clamp(1.5rem, 1.2rem + 1.5vw, 2.5rem);
--space-l: clamp(2rem, 1.5rem + 2.5vw, 4rem);
}
clamp() elimina a necessidade de dezenas de media queries para tipografia. Um valor mínimo, um valor preferido que escala com a viewport, um valor máximo. O resultado é tipografia que flui organicamente de mobile a desktop sem saltos.
Media queries respondem ao viewport. Container queries respondem ao container pai. Essa distinção é fundamental para componentes reutilizáveis.
/* Media queries: o componente sabe o tamanho da JANELA */
@media (min-width: 768px) {
.card { flex-direction: row; }
}
/* Container queries: o componente sabe o tamanho do SEU ESPAÇO */
.card-container {
container-type: inline-size;
container-name: card-wrapper;
}
@container card-wrapper (min-width: 400px) {
.card {
flex-direction: row;
gap: var(--space-m);
}
}
@container card-wrapper (min-width: 600px) {
.card {
grid-template-columns: 200px 1fr;
}
}
Um card dentro de um sidebar de 300px se comporta diferente do mesmo card em uma grid full-width de 1200px — mesmo que o viewport seja o mesmo. Container queries resolvem isso nativamente. A IA quase sempre gera media queries, porque são mais prevalentes no training data.
O Google recomenda touch targets mínimos de 48x48px com pelo menos 8px de espaçamento entre eles. A Apple sugere 44x44pt. A IA frequentemente gera botões e links com áreas de toque menores, especialmente em listas e navegação.
/* Touch target mínimo acessível */
.action-button {
min-height: 48px;
min-width: 48px;
padding: 12px 24px;
/* Área de toque expandida sem mudar visual */
position: relative;
}
.action-button::after {
content: '';
position: absolute;
inset: -8px; /* Expande área de toque 8px em cada direção */
}
50% da população mundial acessa a internet com conexões intermitentes. No Brasil, regiões inteiras dependem de 3G. Um front-end engineer pensa em conectividade como espectro, não como binário.
// Estratégia de cache com stale-while-revalidate
async function fetchWithFallback(url, cacheKey) {
const cache = await caches.open('app-cache-v1');
try {
const response = await fetch(url, {
signal: AbortSignal.timeout(5000)
});
// Salva no cache para uso offline
cache.put(cacheKey, response.clone());
return response.json();
} catch (error) {
// Sem conexão? Usa cache
const cached = await cache.match(cacheKey);
if (cached) {
return {
data: await cached.json(),
isStale: true // UI pode indicar "dados podem estar desatualizados"
};
}
throw new OfflineError('Sem conexão e sem cache disponível');
}
}
O front-end é a camada mais exposta do stack. Está no dispositivo do usuário, sujeita a condições que nenhum ambiente de desenvolvimento simula: extensões de browser interferindo, ad blockers removendo scripts, APIs falhando, CDNs caindo, text desabilitado.
// Error boundary que IA nunca gera proativamente
class ProductErrorBoundary extends React.Component {
state = { hasError: false, error: null };
static getDerivedStateFromError(error) {
return { hasError: true, error };
}
componentDidCatch(error, errorInfo) {
// Log para observabilidade — não só console.error
monitoring.captureException(error, {
component: 'ProductCard',
extra: errorInfo
});
}
render() {
if (this.state.hasError) {
return (
<article className="card card--error" role="alert">
<p>Não foi possível carregar este produto.</p>
<button
onClick={() => this.setState({ hasError: false })}
type="button"
>
Tentar novamente
</button>
</article>
);
}
return this.props.children;
}
}
// Uso: cada card falha independentemente
<ul className="product-grid" role="list">
{products.map(product => (
<li key={product.id}>
<ProductErrorBoundary>
<ProductCard product={product} />
</ProductErrorBoundary>
</li>
))}
</ul>
Se um produto tem dados corrompidos, apenas aquele card mostra erro. Os outros 23 continuam funcionais. Sem error boundary, um produto com bug derruba a página inteira.
A percepção de velocidade importa tanto quanto a velocidade real. Skeleton screens reduzem a percepção de espera porque o usuário vê estrutura, não vazio.
/* Skeleton com animação de shimmer — padrão engenheirado */
.skeleton {
background: linear-gradient(
90deg,
var(--skeleton-base, #e0e0e0) 25%,
var(--skeleton-shine, #f0f0f0) 50%,
var(--skeleton-base, #e0e0e0) 75%
);
background-size: 200% 100%;
animation: shimmer 1.5s ease-in-out infinite;
border-radius: 4px;
}
@keyframes shimmer {
0% { background-position: 200% 0; }
100% { background-position: -200% 0; }
}
/* Respeita preferência de motion reduzido */
@media (prefers-reduced-motion: reduce) {
.skeleton {
animation: none;
opacity: 0.7;
}
}
Observe o prefers-reduced-motion. Pessoas com distúrbios vestibulares podem sentir náusea com animações contínuas. Um detalhe que separa engenharia de geração automática: empatia codificada.
Cerca de 1-2% dos page views não executam text completamente. Parece pouco, mas em sites com milhões de acessos, são dezenas de milhares de sessões por dia.
<!-- Progressive enhancement: funciona sem JS, melhora com JS -->
<form action="/search" method="GET" class="search-form">
<label for="search-input" class="sr-only">Buscar produtos</label>
<input
type="search"
id="search-input"
name="q"
placeholder="Buscar produtos..."
autocomplete="off"
>
<button type="submit">Buscar</button>
</form>
<script>
// Enhancement: adiciona busca em tempo real se JS disponível
const form = document.querySelector('.search-form');
const input = form.querySelector('input');
form.addEventListener('submit', (e) => {
e.preventDefault(); // Só previne submit se JS funcionar
performLiveSearch(input.value);
});
input.addEventListener('input',
debounce(() => performLiveSearch(input.value), 300)
);
</script>
Sem text: o formulário faz submit normal, o servidor retorna uma página com resultados. Com text: busca em tempo real, resultados instantâneos. Ambos funcionam. Progressive enhancement não é uma técnica vintage — é engenharia resiliente.
A Peak-End Rule da psicologia cognitiva nos diz que pessoas julgam experiências com base nos momentos de pico e no momento final. Micro-interações criam esses picos memoráveis.
Mas animação no front-end não é decoração. É comunicação. Um botão que pulsa ao receber hover comunica interatividade. Uma transição suave ao navegar entre páginas comunica continuidade. Um feedback háptico (visuais) ao completar uma ação comunica confirmação.
/* Transição de estado que comunica, não decora */
.add-to-cart-button {
--btn-bg: var(--color-primary);
--btn-scale: 1;
background: var(--btn-bg);
transform: scale(var(--btn-scale));
transition:
background 200ms ease-out,
transform 150ms cubic-bezier(0.34, 1.56, 0.64, 1);
}
.add-to-cart-button:hover {
--btn-scale: 1.02;
}
.add-to-cart-button:active {
--btn-scale: 0.97;
transition-duration: 50ms;
}
.add-to-cart-button[data-state="success"] {
--btn-bg: var(--color-success);
animation: confirmPulse 400ms ease-out;
}
@keyframes confirmPulse {
0% { box-shadow: 0 0 0 0 rgba(var(--color-success-rgb), 0.4); }
100% { box-shadow: 0 0 0 16px rgba(var(--color-success-rgb), 0); }
}
/* Novamente: respeita preferência do usuário */
@media (prefers-reduced-motion: reduce) {
.add-to-cart-button {
transition-duration: 0ms;
}
.add-to-cart-button[data-state="success"] {
animation: none;
outline: 3px solid var(--color-success);
}
}
A IA gera animação como efeito visual. O engenheiro implementa animação como linguagem: cada movimento tem propósito, duração calculada, easing curve intencional e fallback para quem prefere motion reduzido.
O detalhe do cubic-bezier(0.34, 1.56, 0.64, 1) no hover — um leve overshoot que dá sensação orgânica ao scale — é o tipo de refinamento que vem de experimentação, não de geração automática. É a diferença entre um botão que "funciona" e um botão que "encanta".
Seria desonesto — e prejudicaria a credibilidade deste argumento — não reconhecer onde a IA excede.
A IA é excelente para:
Scaffolding e boilerplate. Criar a estrutura inicial de componentes, configurar projetos, gerar código repetitivo que segue padrões estabelecidos. Um novo componente React com TypeScript, props, estado básico? A IA gera em segundos o que levaria 10-15 minutos.
Componentes visuais básicos. Cards, formulários, layouts de grid, navbars — quando o requisito é puramente visual e o happy path é suficiente, a IA produz código funcional rapidamente.
CSS boilerplate. Reset CSS, sistemas de grid, utility classes, temas de cores. A parte mecânica do CSS é commodity.
Prototipagem rápida. Validar ideias de layout, testar hipóteses visuais, criar MVPs para feedback. A velocidade da IA para protótipos é genuinamente transformadora.
Refatoração guiada. Com instruções claras e específicas ("converta este componente de classe para hook"), a IA é um acelerador eficiente.
Testes unitários básicos. Gerar tests para componentes simples, mocks e fixtures — a IA reduz significativamente o trabalho braçal.
O padrão que emerge: a IA é boa na parte do front-end que é mecânica e previsível. Ela falha na parte que é contextual e empática. E é exatamente a parte contextual e empática que define a qualidade da experiência.
Se a IA absorve o trabalho de implementação básica, o que sobra para o engenheiro de front-end? Sobra tudo que importa.
O front-end engineer de 2026 é um curador de experiência. Não escreve cada linha de CSS — mas decide quais linhas precisam existir e quais são desperdício. Não constrói cada componente do zero — mas define os critérios de qualidade que cada componente deve atender. Não implementa cada animação — mas projeta o sistema de motion que dá personalidade ao produto.
O perfil evolui de "pessoa que transforma Figma em HTML/CSS" para:
Arquiteto de performance. Decide a estratégia de rendering, o budget de text, o plano de loading. Faz análise de bundle. Otimiza Critical Rendering Path. Configura Resource Hints. Implementa e monitora Core Web Vitals.
Especialista em acessibilidade. Garante que a aplicação funciona para todos. Faz auditoria WCAG. Testa com tecnologias assistivas. Treina o time. Define padrões de componentes acessíveis.
Designer de resiliência. Projeta como a aplicação se comporta quando as coisas dão errado. Error boundaries, loading states, offline handling, graceful degradation. O cenário de falha é tão projetado quanto o cenário de sucesso.
Engenheiro de interação. Cria micro-interações significativas, sistemas de animação, feedback háptico visual. Entende psicologia cognitiva aplicada a interfaces.
Guardião da qualidade. Revisa código gerado por IA com olhar crítico. Identifica problemas de acessibilidade, performance e resiliência que a IA introduziu. É o controle de qualidade entre o gerado e o publicado.
Esse perfil não é menos técnico que o anterior. É mais. Exige conhecimento profundo de como browsers funcionam, como pessoas com deficiência navegam, como redes se comportam sob estresse, como a percepção humana processa interfaces.
A IA não diminuiu o valor do front-end engineer. Ela filtrou o ruído e revelou o sinal.
Lighthouse é útil, mas é um proxy. Um score 100 no Lighthouse não significa que a experiência é boa — significa que os critérios técnicos mensuráveis estão atendidos. E muitos critérios importantes não são mensuráveis automaticamente.
| Métrica | Bom | Precisa Melhorar | Ruim |
|---|---|---|---|
| LCP | < 2.5s | 2.5s - 4.0s | > 4.0s |
| INP | < 200ms | 200ms - 500ms | > 500ms |
| CLS | < 0.1 | 0.1 - 0.25 | > 0.25 |
| TTFB | < 800ms | 800ms - 1800ms | > 1800ms |
| Total Blocking Time | < 200ms | 200ms - 600ms | > 600ms |
| Métrica | Como Medir | Por Que Importa |
|---|---|---|
| Task Completion Rate | Testes de usabilidade | Usuário conseguiu fazer o que veio fazer? |
| Error Recovery Time | Observação / analytics | Quanto tempo leva para se recuperar de um erro? |
| Acessibilidade percebida | Testes com usuários reais de AT | Screen reader users conseguem navegar eficientemente? |
| Frustração | Rage clicks, rapid scrolling | Sinais de que algo não funciona como esperado |
| Confiança visual | Testes A/B, surveys | Layout shifts e glitches reduzem confiança |
A métrica mais importante não está em nenhuma ferramenta: a pessoa conseguiu realizar sua tarefa com o mínimo de fricção? Isso é o "job to be done" do front-end. Não é fazer bonito. É fazer funcionar. Para todos. Em qualquer condição.
A IA não matou o front-end. Ela matou o front-end superficial — o que era só aparência, só pixel, só layout copiado do Dribbble.
O front-end que sobrevive é o que sempre foi o verdadeiro front-end: engenharia de experiência humana. Acessibilidade que inclui. Performance que respeita o tempo do usuário. Resiliência que funciona quando tudo mais falha. Micro-interações que comunicam com elegância.
A ironia é que, ao automatizar a parte fácil, a IA tornou a parte difícil mais visível e mais valorizada. Agora que qualquer pessoa pode gerar uma interface em 60 segundos, a diferença entre amador e profissional não é mais o visual — é tudo que está por baixo do visual.
E esse "tudo que está por baixo" é engenharia pura. É o ofício de quem entende que um <button> não é uma <div> com onclick. Que loading="lazy" em toda imagem não é otimização — é preguiça. Que outline: none sem alternativa é exclusão. Que 847KB de text para exibir uma lista é violência contra a conexão do usuário.
O front-end que a IA não consegue fazer é, no fundo, o front-end que sempre mereceu ser feito. E a boa notícia? Nunca houve tanta demanda por ele.
<header>, <nav>, <main>, <article>, <footer> em vez de divsalt text significativo (ou alt="" se decorativa)<label> associadoaria-live regions para conteúdo dinâmicosrcset e sizesfetchpriority="high" no LCP elementloading="lazy" em imagens abaixo do fold (não acima!)font-display: swap ou optionalclamp()font-size: 16px)prefers-reduced-motion respeitado em todas as animaçõesO front-end que a IA não faz é o front-end que o usuário mais sente. Invista nos 20% que representam 100% da experiência. A qualidade da interface é uma declaração de respeito pelo tempo, pela atenção e pela dignidade de quem a usa.