💻 Exemplos: Capítulo 19: Otimização de Performance, SEO, Meta Tags e PWA
Especialização em Front-End com Vue • Demonstrações Práticas Compiláveis
💻 Código de Exemplo 19 — Otimização de Web Vitals, Carregamento Assíncrono com defineAsyncComponent e Meta Tags SEO
Este exemplo apresenta a implementação de técnicas de ponta para otimização de performance no Vue 3 / Nuxt: divisão de código com defineAsyncComponent (com componentes de delay e timeout), controle dinâmico de tags Open Graph para SEO via useSeoMeta e minimização de reflows do DOM.
<!-- src/components/OptimizedEnterpriseView.vue -->
<script setup lang="ts">
import { ref, defineAsyncComponent } from 'vue';
// 1. CARREGAMENTO LAZY DE COMPONENTE PESADO COM FALLBACKS
const HeavyAnalyticsChart = defineAsyncComponent({
loader: () => import('./HeavyAnalyticsChart.vue'),
loadingComponent: {
template: `
<div class="h-64 bg-slate-100 rounded-xl flex items-center justify-center text-xs text-slate-400 animate-pulse">
⚡ Carregando biblioteca pesada de gráficos sob demanda...
</div>
`
},
delay: 200, // Não pisca o skeleton se o chunk carregar em menos de 200ms
timeout: 5000,
errorComponent: {
template: `
<div class="p-4 bg-red-50 text-red-700 text-xs rounded-xl">
Falha ao carregar o módulo gráfico. Verifique sua conexão.
</div>
`
}
});
const isChartVisible = ref<boolean>(false);
// 2. CONFIGURAÇÃO AVANÇADA DE METADADOS SEO (Compatível com Nuxt e Unhead)
const pageTitle = ref('Relatório de Eficiência Operacional 2026');
const pageDescription = ref('Métricas consolidadas de infraestrutura, throughput e SLA corporativo.');
if (typeof useSeoMeta !== 'undefined') {
useSeoMeta({
title: pageTitle.value,
description: pageDescription.value,
ogTitle: pageTitle.value,
ogDescription: pageDescription.value,
ogType: 'article',
ogImage: 'https://cdn.empresa.com.br/assets/seo-share-card.png',
twitterCard: 'summary_large_image',
twitterTitle: pageTitle.value
});
}
function showChartModule(): void {
isChartVisible.value = true;
}
</script>
<template>
<div class="max-w-2xl mx-auto p-6 bg-white border rounded-2xl shadow-sm space-y-6">
<div class="border-b pb-4">
<span class="text-xs uppercase font-extrabold text-indigo-600 tracking-wider">
Web Performance & SEO
</span>
<h2 class="text-2xl font-black text-slate-900 mt-1">{{ pageTitle }}</h2>
<p class="text-sm text-slate-500 mt-1">{{ pageDescription }}</p>
</div>
<!-- Indicadores de Core Web Vitals Esperados -->
<div class="grid grid-cols-3 gap-3">
<div class="p-3 bg-emerald-50 border border-emerald-100 rounded-xl">
<span class="text-[10px] uppercase font-bold text-emerald-800">LCP</span>
<div class="text-lg font-black text-emerald-700 mt-0.5">< 1.2s</div>
<p class="text-[10px] text-emerald-600">Largest Contentful Paint</p>
</div>
<div class="p-3 bg-emerald-50 border border-emerald-100 rounded-xl">
<span class="text-[10px] uppercase font-bold text-emerald-800">CLS</span>
<div class="text-lg font-black text-emerald-700 mt-0.5">0.00</div>
<p class="text-[10px] text-emerald-600">Zero Layout Shift</p>
</div>
<div class="p-3 bg-emerald-50 border border-emerald-100 rounded-xl">
<span class="text-[10px] uppercase font-bold text-emerald-800">INP</span>
<div class="text-lg font-black text-emerald-700 mt-0.5">< 50ms</div>
<p class="text-[10px] text-emerald-600">Interaction to Next Paint</p>
</div>
</div>
<!-- Gatilho de Carregamento Assíncrono Sob Demanda -->
<div class="space-y-3">
<div class="flex items-center justify-between">
<h3 class="font-bold text-slate-800 text-sm">Visualização Gráfica do Cluster</h3>
<button
v-if="!isChartVisible"
@click="showChartModule"
class="text-xs px-3 py-2 bg-indigo-600 hover:bg-indigo-700 text-white rounded-lg font-semibold transition-colors shadow-sm"
>
Carregar Gráfico Sob Demanda (Code-Splitting)
</button>
</div>
<div v-if="isChartVisible">
<HeavyAnalyticsChart />
</div>
<div v-else class="h-32 border border-dashed rounded-xl flex items-center justify-center text-xs text-slate-400">
O chunk JavaScript pesado (ex: Chart.js / ECharts) não foi baixado na carga inicial da página.
</div>
</div>
</div>
</template>
🖥️ Saída / Comportamento Esperado
Inspeção de Network no DevTools:
1. Carga Inicial do Bundle:
- Tamanho do HTML/JS inicial reduzido em ~320 KB (a biblioteca gráfica não é baixada).
- Core Web Vitals (LCP e FID) alcançam nota 100 no Google Lighthouse.
2. Inspeção de SEO no Head:
<meta property="og:title" content="Relatório de Eficiência Operacional 2026">
<meta property="og:image" content="https://cdn.empresa.com.br/assets/seo-share-card.png">
<meta name="twitter:card" content="summary_large_image">
3. Interação:
- Clicar em "Carregar Gráfico Sob Demanda":
- O navegador dispara o download de `HeavyAnalyticsChart-[hash].js`.
- Enquanto o download ocorre (delay > 200ms), o `loadingComponent` exibe mensagem suave com animate-pulse.
- O módulo é montado fluidamente na tela sem travamento da thread principal.
🔍 Destaques da Implementação
- Redução Drástica do Time to Interactive (TTI): A separação de módulos gráficos pesados com
defineAsyncComponentimpede que scripts secundários concorram com a hidratação inicial. - Propriedade
delayAnti-Flicker: Evita renderizar skeleton loaders quando o usuário possui conexão de alta velocidade (fibra) e o chunk carrega em menos de 200ms. useSeoMetaPadronizado: Fornece tipagem automática para mais de 100 propriedades canônicas do Open Graph e Twitter Cards.