O problema
Imagine um blog com 50 posts. Se cada post tiver 200KB de JavaScript compilado — JSX, syntax highlighting inline do Shiki, imports — você tem 10MB de bundle só de conteúdo. Carregar tudo isso na home é um desperdício: o usuário veio ver a lista de posts, não ler todos eles.
O Vite resolve isso com import.meta.glob.
Dois modos, dois propósitos
Lazy — download sob demanda
O Vite transforma isso em um objeto de funções:
Nenhum módulo é carregado até você chamar a função. O bundle principal não cresce.
Eager — disponível no boot
O import: "frontmatter" importa apenas o named export frontmatter de cada arquivo. O Vite serializa esses dados como literais no bundle — sem JSX, sem código de componente. O resultado é um objeto já populado quando a aplicação sobe.
A separação na prática
Para listar posts, você só precisa de título, slug, tags e descrição. Esses dados são pequenos e precisam estar disponíveis imediatamente — eager é a escolha certa.
Para renderizar um post específico, você precisa do componente React compilado. Esse é o bundle pesado — lazy com React.lazy() garante que ele só seja baixado quando o usuário navegar até aquela página.
O erro comum
Usar o módulo lazy para ler metadados:
Se o frontmatter já está disponível via eager, não há razão para fazer o download do módulo completo. O resultado é o mesmo, mas o custo de rede é desnecessário.
Table of contents
O ToC de cada post — uma lista de seções com id, texto e profundidade — também é eager:
Isso permite registrar o sumário na sidebar de forma síncrona, sem quebrar o useEffect:
Prefetch no hover
Com os loaders síncronos e os bundles corretamente separados, o prefetch de navegação funciona sem surpresas. Basta configurar o router:
No hover de qualquer link de post, o loader executa instantaneamente — sem download. O bundle MDX só é requisitado quando o componente renderiza de fato.