Voltar ao Blog
    Arquitetura

    Técnicas de Performance que as Big Techs Usam (e você pode aplicar hoje)

    Speculation Rules API, Optimistic UI, Streaming SSR, Priority Hints, Virtual Scrolling, Web Workers, SWR e INP — o que Google, Shopify, Netflix, Meta e Figma fazem de diferente pra ter apps que parecem instantâneos.

    20 de março de 20268 min

    Você abre o Linear, clica num card, a navegação é instantânea. Abre o Figma, arrasta um elemento com centenas de layers, sem travar. Usa o Shopify, clica num produto, a página já tá lá.

    Isso não é mágica. É um conjunto de técnicas de performance que as big techs refinaram ao longo de anos — e que estão disponíveis pra qualquer dev usar.

    Vou mostrar 8 técnicas, com os contextos reais de quem usa e exemplos práticos de como aplicar.

    🔮 1. Speculation Rules API

    A técnica mais relevante do momento. O browser prediz qual página o usuário vai acessar e faz prefetch ou prerender antes da navegação acontecer.

    Tem dois modos:

    • prefetch → paga o custo de TTFB antecipado (só baixa o HTML)
    • prerender → renderiza a página inteira em background (navegação parece instantânea)

    O Shopify configurou com eagerness: conservative — o browser faz prefetch no momento em que o usuário pressiona o botão do mouse, antes mesmo de soltar.

    <script type="speculationrules">
    {
      "prefetch": [{ "where": { "href_matches": "/*" }, "eagerness": "immediate" }],
      "prerender": [{ "where": { "href_matches": "/*" }, "eagerness": "moderate" }]
    }
    </script>
    

    ⚠️ Cuidados importantes

    • Não especule rotas destrutivas como /logout ou /delete
    • Prerender executa todos os scripts — pode causar overreporting em analytics (a página é "visitada" antes do usuário de fato navegar)
    • Use eagerness: conservative ou moderate pra não desperdiçar banda

    Quem usa: Google, Shopify, Cloudflare


    ⚡ 2. Optimistic UI

    Atualiza a UI antes da confirmação do servidor. Se falhar, faz rollback. É o que faz o Linear parecer que tudo acontece instantaneamente.

    O fluxo é simples:

    1. Usuário faz uma ação
    2. UI atualiza imediatamente com um estado temporário
    3. Requisição vai pro servidor em paralelo
    4. Se der certo: substitui o temporário pelo dado real
    5. Se der errado: reverte e mostra o erro
    // Svelte store com optimistic update
    function createEntry(data) {
        const tempId = crypto.randomUUID()
        entries.update(list => [{ ...data, id: tempId, pending: true }, ...list])
    
        api.post('/entries', data)
            .then(real => entries.update(list =>
                list.map(e => e.id === tempId ? real : e)
            ))
            .catch(() => entries.update(list =>
                list.filter(e => e.id !== tempId)
            ))
    }
    

    O estado pending: true serve pra mostrar um indicador visual sutil (loading spinner no item, opacity reduzida) enquanto confirma no servidor.

    Quem usa: Meta, Linear, Vercel


    🌊 3. Streaming SSR + Suspense

    Netflix reduziu o TTI em 50% controlando exatamente o que é renderizado no servidor vs. cliente. A ideia: não bloquear a renderização esperando dados secundários.

    No SvelteKit isso é nativo via load() com streaming — dados sem await são enviados de forma incremental:

    // +page.server.js
    export async function load() {
        return {
            // dados críticos: aguarda antes de enviar o HTML
            user: await getUser(),
    
            // dados secundários: streaming (não bloqueia a renderização)
            entries: getEntries(),  // sem await — chega depois
        }
    }
    

    No React/Next.js, o equivalente é <Suspense> com Server Components. O shell da página chega imediatamente, os dados lentos chegam depois e hidratam o componente no lugar certo.

    Quem usa: Netflix, Vercel


    🎯 4. Priority Hints

    Diz pro browser o que é importante agora e o que pode esperar. Simples, mas poucos usam.

    <!-- Imagem principal acima do fold: alta prioridade -->
    <img fetchpriority="high" src="/hero.webp">
    
    <!-- Imagens abaixo do fold: baixa prioridade -->
    <img fetchpriority="low" loading="lazy" src="/cover.webp">
    
    // Fetch da IA com alta prioridade — usuário está esperando
    fetch('/api/generate', { priority: 'high' })
    
    // Analytics: baixa prioridade, não bloqueia nada
    fetch('/api/track', { priority: 'low' })
    

    O impacto no LCP pode ser significativo. Se o browser trata sua imagem hero com a mesma prioridade que um pixel de rastreamento, você tá perdendo performance de graça.

    Quem usa: Google


    📜 5. Virtual Scrolling

    Timeline com centenas (ou milhares) de registros — o DOM renderiza só o que está visível na tela. O resto é calculado matematicamente mas não existe no DOM.

    O Google Sheets faz isso com suas células. O Linear faz com issues. O Notion faz com blocos longos.

    // Com svelte-virtual (equivalente ao react-window no React)
    import { VirtualList } from 'svelte-virtual'
    
    <VirtualList items={entries} itemHeight={80} let:item>
        <EntryCard {item} />
    </VirtualList>
    

    Sem virtual scrolling, uma lista de 5000 itens cria 5000 nós no DOM. Com virtual scrolling, você cria só os ~15 que aparecem na tela, independente do tamanho da lista.

    Quem usa: Google Sheets, Linear, Notion


    🧵 6. Web Workers para Operações Pesadas

    Geração de PDF, cálculo de embeddings, parsing de arquivos grandes — tudo isso bloqueia a main thread se rodar no componente. A solução: mover pra um Web Worker.

    O Figma roda praticamente toda a lógica de renderização em Workers, mantendo a UI fluida mesmo com operações pesadas.

    // worker.js
    self.onmessage = async ({ data }) => {
        const pdf = await generatePDF(data.entries)
        self.postMessage({ pdf })
    }
    
    // componente
    const worker = new Worker('/workers/pdf.js')
    worker.postMessage({ entries })
    worker.onmessage = ({ data }) => downloadPDF(data.pdf)
    

    A regra geral: qualquer operação que leva mais de 50ms é candidata a ir pra um Worker.

    Quem usa: Figma, Google Docs


    🔄 7. SWR / Stale-While-Revalidate

    Mostra o dado em cache imediatamente, revalida em background. O usuário vê algo útil na hora, e os dados ficam frescos em seguida.

    No SvelteKit, você pode configurar isso diretamente nos headers de resposta:

    // +page.server.js
    export async function load({ fetch, setHeaders }) {
        setHeaders({
            'cache-control': 'max-age=60, stale-while-revalidate=300'
        })
    
        return {
            entries: await fetch('/api/entries').then(r => r.json())
        }
    }
    

    Com essa config: dados com menos de 60s são servidos do cache direto. Entre 60s e 5min, o cache velho é servido enquanto a revalidação acontece em background.

    Quem usa: Vercel (criou o padrão com a lib SWR), GitHub


    📊 8. INP — A Nova Métrica Core Web Vitals

    Em março de 2024, o INP (Interaction to Next Paint) substituiu o FID como Core Web Vital. A diferença é sutil mas importante:

    • FID mede só a primeira interação do usuário
    • INP mede todas as interações — cliques, toques, teclas — e retorna a pior

    Isso significa que uma página pode ter FID excelente mas INP ruim se tiver alguma interação lenta no meio da sessão.

    Como otimizar INP

    scheduler.yield() — cede controle ao browser entre tarefas longas:

    async function handleGenerateAI() {
        updateUI('loading')
        await scheduler.yield()  // browser pinta o loading antes de continuar
        const result = await callClaude()
        updateUI('done', result)
    }
    

    Outras técnicas:

    • Debounce em inputs que disparam cálculos pesados
    • Evitar layout thrashing — ler e escrever DOM separadamente
    • Quebrar tarefas longas com setTimeout(fn, 0) ou scheduler.postTask()

    Quem criou e monitora: Google


    📋 Resumo por Empresa

    TécnicaQuem usa
    Speculation Rules APIGoogle, Shopify, Cloudflare
    Optimistic UIMeta, Linear, Vercel
    Streaming SSRNetflix, Vercel
    Priority HintsGoogle
    Virtual ScrollingGoogle Sheets, Linear, Notion
    Web WorkersFigma, Google Docs
    SWRVercel, GitHub
    INP optimizationGoogle (própria métrica)

    Nenhuma dessas técnicas exige um framework específico ou uma infraestrutura especial. Speculation Rules é um <script> no HTML. Priority Hints é um atributo. SWR é um header HTTP.

    O que separa apps lentos de apps rápidos geralmente não é uma grande reescrita — é a soma de pequenas decisões bem tomadas.

    Para discussões técnicas ou dúvidas sobre implementação, me encontre no LinkedIn ou GitHub.

    Acompanhe mais conteúdo em eliseu.dev e na MFE Brasil Newsletter.