Desempenho do Vue 3 em 2026: Vapor Mode, Alien Signals e o fim do Virtual DOM
Mergulho no desempenho do Vapor Mode do Vue 3.6: como ele elimina o Virtual DOM, o sistema de reatividade Alien Signals, benchmarks contra o Solid.js e técnicas práticas de otimização para produção.

O Vapor Mode do Vue 3.6 representa a mudança de arquitetura de renderização mais significativa desde que o Vue adotou o Virtual DOM na versão 2. Ao compilar os Single File Components diretamente em operações imperativas de DOM, o Vapor Mode elimina o custo de diffing que definiu o pipeline de renderização do Vue por anos. Combinado com a reescrita do sistema de reatividade Alien Signals, o Vue 3.6 alcança paridade de benchmark com o Solid.js e o Svelte 5, sem exigir que os desenvolvedores aprendam uma nova API.
O Vapor Mode é uma estratégia de compilação opcional no Vue 3.6 que ignora completamente o Virtual DOM. Os componentes compilados em Vapor Mode ligam cada dependência reativa diretamente ao nó exato do DOM que ela afeta, produzindo atualizações cirúrgicas sem nenhuma travessia de árvore. A ativação acontece com um único atributo: <script setup vapor>.
Como funciona o Virtual DOM do Vue: por que ele virou um gargalo
O padrão Virtual DOM (VDOM), popularizado pelo React e adotado pelo Vue 2, cria uma representação leve em JavaScript da árvore real do DOM. A cada mudança de estado, o Vue gera uma nova árvore VDOM, compara com a anterior e aplica ao DOM real apenas os nós que mudaram.
Essa abordagem funciona bem para a maioria das aplicações. O algoritmo de diffing roda em tempo O(n), e o compilador do Vue já exclui as subárvores estáticas do caminho de comparação. Mas o custo se acumula em cenários específicos:
- Listas grandes com centenas de linhas disparam comparações completas de subárvores a cada atualização
- Mudanças de estado frequentes (animações, dados em tempo real) geram uma rotatividade de VDOM que o coletor de lixo precisa limpar
- Árvores de componentes profundas multiplicam o custo da travessia da árvore e da geração de patches
O compilador de templates do Vue 3 introduziu várias otimizações de VDOM (hoisting estático, patch flags, block trees) que reduziram o trabalho desnecessário. Elas trouxeram melhorias mensuráveis, mas a arquitetura fundamental ainda exigia gerar, comparar e descartar objetos JavaScript a cada ciclo de renderização.
Vue 3.6 Vapor Mode: compilar para eliminar o Virtual DOM
O Vapor Mode adota uma abordagem totalmente diferente. Em vez de compilar os templates em funções de renderização que retornam nós VDOM, o compilador Vapor gera código que cria e atualiza diretamente os elementos do DOM. Cada vínculo reativo corresponde a uma mutação específica do DOM, sem nenhuma representação intermediária.
Veja como um componente Vue padrão é compilado de forma diferente em cada modo:
<!-- Counter.vue -->
<script setup vapor>
import { ref } from 'vue'
const count = ref(0)
const increment = () => count.value++
</script>
<template>
<button @click="increment">
Count: {{ count }}
</button>
</template>No modo VDOM clássico, esse template é compilado em uma função de renderização que retorna uma árvore de nós virtuais. A cada clique, o Vue cria uma nova árvore VDOM, compara com a anterior, detecta que o conteúdo de texto mudou e aplica o patch ao DOM real.
No Vapor Mode, o compilador gera algo mais próximo disto:
// Saída de compilação Vapor (simplificada)
const button = document.createElement('button')
const text = document.createTextNode('Count: 0')
button.appendChild(text)
// Vínculo direto: fonte reativa -> mutação do DOM
effect(() => {
text.nodeValue = `Count: ${count.value}`
})
button.addEventListener('click', increment)O efeito reativo liga count diretamente a text.nodeValue. Sem criação de VDOM, sem diffing, sem patching. A mudança de estado dispara exatamente uma mutação do DOM.
Habilitando o Vapor Mode em um projeto
O Vapor Mode opera no nível do componente. Existem duas estratégias de integração:
import { createVaporApp } from 'vue'
import App from './App.vue'
createVaporApp(App).mount('#app')import { createApp, vaporInteropPlugin } from 'vue'
import App from './App.vue'
createApp(App)
.use(vaporInteropPlugin)
.mount('#app')A abordagem híbrida permite uma migração gradual. Componentes críticos em desempenho, tabelas de dados, painéis em tempo real, telas com muitas animações, podem adotar o Vapor enquanto o restante da aplicação continua usando o runtime padrão de VDOM. Os dois tipos de componente coexistem na mesma árvore.
O Vapor Mode exige a Composition API com <script setup>. A Options API, app.config.globalProperties, getCurrentInstance() e os eventos de ciclo de vida por elemento (@vue:mounted, etc.) não são suportados. As diretivas personalizadas usam uma interface diferente que aceita getters reativos em vez de objetos de binding. O Suspense funciona ao envolver componentes Vapor dentro de um pai VDOM, mas não em aplicações 100% Vapor.
Alien Signals: o novo motor de reatividade do Vue
O Vue 3.6 traz uma segunda grande mudança ao lado do Vapor Mode: uma reescrita completa do @vue/reactivity baseada na biblioteca Alien Signals. Criada por Johnson Chu, a Alien Signals implementa um algoritmo de reatividade push-pull que reduz tanto a alocação de memória quanto o custo de computação.
O modelo push-pull funciona em duas fases:
- Fase push: quando um signal (fonte reativa) muda, ele propaga uma flag «dirty» para todas as propriedades computadas dependentes. Essa travessia é barata: apenas alterna flags booleanas sem executar nenhum cálculo.
- Fase pull: quando uma propriedade computada é lida, ela verifica sua flag dirty. Se estiver dirty, recalcula. Se estiver limpa, retorna imediatamente o valor em cache.
Esse design elimina recálculos desnecessários. No sistema de reatividade do Vue 3.5, uma propriedade computada que dependia de três signals recalculava sempre que qualquer signal mudava, mesmo que o resultado permanecesse o mesmo. A Alien Signals só recalcula quando o valor é de fato lido e pelo menos uma dependência mudou.
import { ref, computed, watch } from 'vue'
const firstName = ref('Jane')
const lastName = ref('Doe')
const isActive = ref(true)
// Este computed só recalcula quando é lido E está dirty
const displayName = computed(() => {
return isActive.value
? `${firstName.value} ${lastName.value}`
: 'Inactive User'
})
// Alterar isActive marca displayName como dirty
// Mas nenhum cálculo roda até que algo leia displayName.value
isActive.value = false
// AGORA o recálculo acontece
console.log(displayName.value) // 'Inactive User'A estrutura de dados interna também mudou. A Alien Signals substitui o rastreamento de dependências baseado em Set por listas duplamente encadeadas, reduzindo a memória por dependência reativa e acelerando a travessia durante a limpeza.
Resultados de benchmark: Alien Signals na prática
Os números dos benchmarks do beta do Vue 3.6 mostram melhorias consistentes em relação ao Vue 3.5:
| Métrica | Vue 3.5 | Vue 3.6 (Alien Signals) | Melhoria | |---|---|---|---| | Memória por ref reativa | Base | -14% | Menor alocação | | Recálculo de computed | Base | -20% em média | Menos execuções desnecessárias | | Montagem de componentes (100k) | ~300 ms | ~100 ms | 3x mais rápido | | First Contentful Paint | Base | 0,7 s típico | Menor custo do framework | | Tamanho do bundle base | ~16 KB | <10 KB | -37% |
Esses ganhos se aplicam automaticamente a todas as aplicações Vue 3.6. Diferentemente do Vapor Mode, que exige adesão por componente, o sistema de reatividade Alien Signals vem ativado por padrão no Vue 3.6.
Pronto para mandar bem nas entrevistas de Vue.js / Nuxt.js?
Pratique com nossos simuladores interativos, flashcards e testes tecnicos.
Técnicas práticas de otimização de desempenho no Vue 3
O Vapor Mode e a Alien Signals atacam o custo no nível do framework, mas o desempenho no nível da aplicação ainda depende de como os componentes são estruturados. Estas técnicas se aplicam a componentes VDOM e Vapor.
Reatividade superficial para grandes estruturas de dados
A reatividade profunda envolve cada propriedade aninhada em um Proxy. Para grandes conjuntos de dados, respostas de API, objetos de configuração, estado em cache, isso cria milhares de wrappers Proxy desnecessários. shallowRef e shallowReactive limitam a reatividade à referência de nível superior.
import { shallowRef, triggerRef } from 'vue'
interface Product {
id: number
name: string
variants: { sku: string; price: number }[]
}
// Apenas a própria ref é reativa, não as propriedades aninhadas
const products = shallowRef<Product[]>([])
// Buscando dados: atribuir o novo array dispara a reatividade
async function fetchProducts() {
const response = await fetch('/api/products')
products.value = await response.json() // dispara a atualização
}
// Mutando dados aninhados: é preciso disparar manualmente
function updatePrice(productId: number, sku: string, newPrice: number) {
const product = products.value.find(p => p.id === productId)
const variant = product?.variants.find(v => v.sku === sku)
if (variant) {
variant.price = newPrice
triggerRef(products) // disparo explícito necessário
}
}A diretiva v-memo para renderização custosa de listas
Para componentes VDOM que renderizam listas longas, v-memo armazena em cache o resultado da renderização de uma subárvore com base em valores de dependência. O VDOM ignora completamente o diffing de subárvores memoizadas cujas dependências não mudaram.
<!-- ProductGrid.vue -->
<script setup>
import { ref } from 'vue'
const products = ref([])
const selectedId = ref(null)
</script>
<template>
<div class="grid">
<div
v-for="product in products"
:key="product.id"
v-memo="[product.id === selectedId, product.price]"
:class="{ selected: product.id === selectedId }"
>
<h3>{{ product.name }}</h3>
<span>{{ product.price }}</span>
</div>
</div>
</template>O array de v-memo [product.id === selectedId, product.price] diz ao Vue: não renderize este item novamente a menos que o estado de seleção ou o preço tenham mudado. Para uma lista de 500 produtos em que apenas um é selecionado, isso reduz o trabalho do VDOM de 500 comparações de subárvores para 2 (o item antes selecionado e o recém-selecionado).
Componentes assíncronos com Suspense para divisão de código
Carregar componentes pesados sob demanda mantém o bundle inicial enxuto. O defineAsyncComponent do Vue, junto com Suspense, gerencia o estado de carregamento de forma declarativa.
<!-- Dashboard.vue -->
<script setup>
import { defineAsyncComponent } from 'vue'
// Biblioteca de gráficos pesada carregada apenas quando necessário
const AnalyticsChart = defineAsyncComponent(() =>
import('./components/AnalyticsChart.vue')
)
const DataExport = defineAsyncComponent({
loader: () => import('./components/DataExport.vue'),
delay: 200, // mostra o carregamento após 200 ms
timeout: 10000, // falha após 10 s
})
</script>
<template>
<Suspense>
<template #default>
<AnalyticsChart />
<DataExport />
</template>
<template #fallback>
<div class="skeleton-loader" />
</template>
</Suspense>
</template>Vapor Mode vs VDOM: quando usar cada abordagem
O Vapor Mode não é um substituto universal do Virtual DOM. Cada modo de compilação tem forças adequadas a perfis diferentes de componentes.
| Cenário | Modo recomendado | Motivo | |---|---|---| | Tabelas de dados (1000+ linhas) | Vapor | Elimina o custo de VDOM por linha | | Painéis em tempo real | Vapor | Atualizações frequentes se beneficiam do vínculo direto ao DOM | | Componentes com muitas animações | Vapor | Sem pressão sobre o GC pela rotatividade de VDOM | | Bibliotecas de componentes de terceiros em VDOM | VDOM | A camada de interoperabilidade adiciona complexidade | | Componentes que usam a Options API | VDOM | O Vapor exige a Composition API | | Formulários com validação complexa | Qualquer um | Custo de renderização mínimo em ambos os modos | | Páginas de conteúdo estático | Qualquer um | O SSG/SSR faz o trabalho pesado |
O caminho de migração recomendado: primeiro fazer o profiling da aplicação com a aba Performance do Vue DevTools. Identificar os componentes com maior tempo de renderização e frequência de re-renderização. Convertê-los para Vapor Mode, medir o impacto e expandir a partir daí.
Perguntas de entrevista: desempenho do Vue 3 e Vapor Mode
Estas perguntas refletem o que as equipes de engenharia perguntam ao avaliar a expertise em Vue em 2026. Cada resposta resume o raciocínio técnico que um entrevistador espera.
P: Que problema o Vapor Mode resolve e como ele difere das otimizações de VDOM que o Vue já tinha?
O compilador de VDOM do Vue 3 já otimizava subárvores estáticas, adicionava patch flags e implementava block trees para pular comparações desnecessárias. Isso reduzia o custo do VDOM, mas não o eliminava: toda mudança de estado ainda exigia criar nós VDOM, percorrer a árvore e gerar patches. O Vapor Mode remove todo esse pipeline. O compilador mapeia o estado reativo diretamente para mutações do DOM, de modo que uma mudança de estado dispara exatamente as operações de DOM necessárias: sem estruturas de dados intermediárias, sem algoritmo de comparação e sem coleta de nós VDOM descartados.
P: Componentes Vapor e VDOM podem coexistir na mesma aplicação?
Sim. O vaporInteropPlugin permite os dois tipos de componente em uma única árvore. Um pai VDOM pode renderizar filhos Vapor e vice-versa, com algumas ressalvas: os slots Vapor não podem usar slots.default() dentro de um componente VDOM (use renderSlot no lugar), e a interoperabilidade com bibliotecas de componentes baseadas em VDOM (Vuetify, PrimeVue) pode ter arestas durante a fase experimental.
P: Explique o modelo de reatividade push-pull dos Alien Signals no Vue 3.6.
O modelo push-pull divide as atualizações reativas em duas fases. Na fase push, quando um signal muda de valor, o sistema propaga uma flag dirty rio abaixo para todas as propriedades computadas dependentes: é barato, pois apenas alterna flags booleanas. Na fase pull, quando um valor computado é de fato lido, ele verifica se está dirty. Se estiver, recalcula a partir de suas dependências. Caso contrário, retorna o valor em cache. Isso evita recalcular antecipadamente propriedades computadas que talvez nunca sejam lidas durante um ciclo de atualização específico.
P: Quando shallowRef deve ser usado em vez de ref em uma aplicação Vue 3?
shallowRef é apropriado quando a estrutura de dados é grande e apenas a reatribuição de nível superior deve disparar a reatividade: caches de respostas de API, objetos de configuração e arrays grandes em que as mutações de itens individuais são controladas manualmente com triggerRef(). A reatividade profunda envolve cada propriedade aninhada em um Proxy, um custo desnecessário para dados que serão substituídos por completo em vez de mutados no lugar.
Para praticar mais, confira as perguntas de entrevista de Vue.js sobre composables e padrões de reatividade na SharpSkill.
O guia oficial de desempenho do Vue.js cobre outras técnicas de otimização, incluindo estabilidade de props, scroll virtual e streaming em SSR. As notas de versão do beta do Vue 3.6 documentam cada API do Vapor Mode e suas limitações conhecidas.
Comece a praticar!
Teste seus conhecimentos com nossos simuladores de entrevista e testes tecnicos.
Conclusão
- O Vapor Mode compila os SFCs do Vue em operações diretas do DOM, eliminando por completo o custo de criação, comparação e patching do Virtual DOM
- A ativação é por componente com
<script setup vapor>, sem necessidade de migração em toda a aplicação - A Alien Signals, o novo motor de reatividade padrão, reduz o uso de memória em 14% e melhora o desempenho das propriedades computadas por meio da avaliação preguiçosa push-pull
- Use
shallowRefpara grandes estruturas de dados,v-memopara renderização custosa de listas edefineAsyncComponentpara divisão de código: esses padrões valem tanto no modo VDOM quanto no Vapor - O Vapor Mode exige a Composition API com
<script setup>. A Options API,getCurrentInstance()eglobalPropertiesnão são suportados - Faça o profiling primeiro com o Vue DevTools, converta os componentes de maior impacto para Vapor, meça e itere
- O Vue 3.6 está em beta no início de 2026: trate o Vapor Mode como experimental para produção, mas comece desde já a desenvolver a familiaridade da equipe
Tags
Compartilhar
Artigos relacionados

Composables Avançados no Vue 3: Padrões Reutilizáveis e Perguntas de Entrevista 2026
Domine composables avançados do Vue 3 com padrões reutilizáveis, tipagem TypeScript e perguntas frequentes de entrevistas técnicas. Guia completo com exemplos práticos de composição, validação de formulários, injeção de dependências e testes unitários.

Nuxt 4 em 2026: nova estrutura de diretórios e migração do Nuxt 3
Guia completo de migração para o Nuxt 4: estrutura de diretórios app/, camada singleton de busca de dados, melhorias no TypeScript e instruções passo a passo com exemplos de código.

Vue 3 Pinia vs Vuex: Gerenciamento de Estado Moderno e Perguntas de Entrevista 2026
Comparação detalhada entre Pinia e Vuex: design de API, suporte TypeScript, Composition API, desempenho, estratégias de migração e perguntas frequentes em entrevistas Vue para 2026.