[{"data":1,"prerenderedAt":1073},["ShallowReactive",2],{"lastUpdated":3,"blog-de-69-a-97-no-lighthouse-pt-BR":4},"2026-09-08",{"post":5,"displayLang":1071,"isFallback":1072,"hasOtherLang":1059},{"id":6,"title":7,"body":8,"category":75,"date":1056,"description":1057,"extension":1058,"featured":1059,"meta":1060,"navigation":1059,"path":1061,"seo":1062,"stem":1063,"tags":1064,"__hash__":1070},"blog/blog/de-69-a-97-no-lighthouse.md","De 66 a 97 no Core Web Vitals: O que identificamos para melhorar na vitrine do PN Imóveis",{"type":9,"value":10,"toc":1039},"minimark",[11,15,36,43,46,217,220,225,236,248,250,258,277,283,460,463,465,469,488,499,509,512,514,518,528,554,557,562,602,604,608,611,622,635,648,650,654,657,753,755,759,766,773,780,800,898,902,946,948,952,955,986,988,992,1021,1023,1027,1035],[12,13,7],"h1",{"id":14},"de-66-a-97-no-core-web-vitals-o-que-identificamos-para-melhorar-na-vitrine-do-pn-imóveis",[16,17,18,19,26,27,31,32,35],"p",{},"A nota de Performance da home do ",[20,21,25],"a",{"href":22,"rel":23},"https://pnimoveis.com.br",[24],"nofollow","pnimoveis.com.br"," no Lighthouse foi de ",[28,29,30],"strong",{},"66 para 97",". O LCP — o tempo até o maior elemento visível aparecer — caiu de ",[28,33,34],{},"6,8 s para 2,0 s"," num celular médio em rede 4G lenta. Acessibilidade subiu de 84 para 96, SEO de 83 para 100, e o site passou a ter prévia de link decente no WhatsApp, coisa que simplesmente não existia.",[16,37,38],{},[39,40],"img",{"alt":41,"src":42},"Lighthouse Score: De 66 para 97","/blog/de-69-a-97-no-lighthouse/image.png",[16,44,45],{},"Este texto conta o caminho: o que encontramos, por que cada coisa doía, o que mudamos e como resolvemos cada gargalo.",[47,48,49,65],"table",{},[50,51,52],"thead",{},[53,54,55,59,62],"tr",{},[56,57,58],"th",{},"Métrica",[56,60,61],{},"Antes",[56,63,64],{},"Depois (Produção)",[66,67,68,84,99,113,127,142,157,172,187,202],"tbody",{},[53,69,70,76,79],{},[71,72,73],"td",{},[28,74,75],{},"Performance",[71,77,78],{},"66",[71,80,81],{},[28,82,83],{},"97",[53,85,86,91,94],{},[71,87,88],{},[28,89,90],{},"Acessibilidade",[71,92,93],{},"84",[71,95,96],{},[28,97,98],{},"96",[53,100,101,106,108],{},[71,102,103],{},[28,104,105],{},"Boas Práticas",[71,107,98],{},[71,109,110],{},[28,111,112],{},"100",[53,114,115,120,123],{},[71,116,117],{},[28,118,119],{},"SEO",[71,121,122],{},"83",[71,124,125],{},[28,126,112],{},[53,128,129,134,137],{},[71,130,131],{},[28,132,133],{},"First Contentful Paint",[71,135,136],{},"2,5 s",[71,138,139],{},[28,140,141],{},"1,2 s",[53,143,144,149,152],{},[71,145,146],{},[28,147,148],{},"Largest Contentful Paint",[71,150,151],{},"6,8 s",[71,153,154],{},[28,155,156],{},"2,0 s",[53,158,159,164,167],{},[71,160,161],{},[28,162,163],{},"Speed Index",[71,165,166],{},"4,1 s",[71,168,169],{},[28,170,171],{},"2,9 s",[53,173,174,179,182],{},[71,175,176],{},[28,177,178],{},"Cumulative Layout Shift",[71,180,181],{},"0,004",[71,183,184],{},[28,185,186],{},"0",[53,188,189,194,197],{},[71,190,191],{},[28,192,193],{},"Total Blocking Time",[71,195,196],{},"170 ms",[71,198,199],{},[28,200,201],{},"130 ms",[53,203,204,209,212],{},[71,205,206],{},[28,207,208],{},"Bytes transferidos na home",[71,210,211],{},"2,8 MB",[71,213,214],{},[28,215,216],{},"~0,6 MB",[218,219],"hr",{},[221,222,224],"h2",{"id":223},"o-paciente","O paciente",[16,226,227,228,231,232,235],{},"O PN Imóveis é a vitrine pública de uma imobiliária de Pernambuco: home com destaques, busca com filtros, página de cada imóvel, e um painel administrativo para os corretores. Stack: ",[28,229,230],{},"Nuxt 4"," (Vue) com ",[28,233,234],{},"PrimeVue",", API no mesmo processo (Nitro), PostgreSQL via Supabase self-hosted, tudo numa VPS com Coolify. As fotos dos imóveis ficam num bucket do Supabase Storage servido por um subdomínio atrás do Cloudflare.",[16,237,238,239,242,243,247],{},"Uma decisão antiga do projeto importa para a história: o app inteiro era uma ",[28,240,241],{},"SPA"," — ",[244,245,246],"code",{},"ssr: false",". O servidor entregava uma casca vazia de HTML e o navegador montava tudo com JavaScript. Fazia sentido para o painel administrativo; para a vitrine, veremos que não.",[218,249],{},[221,251,253,254,257],{"id":252},"o-relatório-dizia-pouco-o-curl-disse-tudo","O relatório dizia pouco. O ",[244,255,256],{},"curl"," disse tudo.",[16,259,260,261,265,266,265,269,272,273,276],{},"O ponto de partida foi o Lighthouse: Performance 66, LCP 6,8 s, e uma lista de auditorias com nomes genéricos — ",[262,263,264],"em",{},"\"Use efficient cache lifetimes (1.352 KiB)\"",", ",[262,267,268],{},"\"Reduce unused JavaScript (692 KiB)\"",[262,270,271],{},"\"Improve image delivery (1.190 KiB)\"",". O PDF é o resumo; não diz ",[262,274,275],{},"quais"," recursos estavam impactando a página.",[16,278,279,280,282],{},"Então fizemos o básico: baixamos a página com ",[244,281,256],{}," e inspecionamos a resposta bruta.",[47,284,285,301],{},[50,286,287],{},[53,288,289,292,295,298],{},[56,290,291],{},"Recurso",[56,293,294],{},"Tamanho",[56,296,297],{},"Cache",[56,299,300],{},"O problema",[66,302,303,321,340,362,381,403,423,441],{},[53,304,305,310,315,318],{},[71,306,307],{},[28,308,309],{},"O HTML da home",[71,311,312],{},[28,313,314],{},"501 KB",[71,316,317],{},"Nenhum",[71,319,320],{},"Uma SPA deveria entregar ~10 KB de casca. Vinham 462 KB de CSS embutido.",[53,322,323,328,334,337],{},[71,324,325],{},[28,326,327],{},"JS de entrada",[71,329,330,333],{},[28,331,332],{},"504 KB"," (146 KB gzip)",[71,335,336],{},"1 ano",[71,338,339],{},"Registrava globalmente todos os ~90 componentes do PrimeVue.",[53,341,342,347,353,355],{},[71,343,344],{},[28,345,346],{},"Imagem do hero",[71,348,349,352],{},[28,350,351],{},"359 KB"," (JPEG 1920px)",[71,354,317],{},[71,356,357,358,361],{},"Era o LCP — e estava como ",[244,359,360],{},"background-image"," no CSS.",[53,363,364,369,375,378],{},[71,365,366],{},[28,367,368],{},"Foto de card",[71,370,371,374],{},[28,372,373],{},"500–565 KB"," (WebP 2000px)",[71,376,377],{},"4 horas",[71,379,380],{},"Exibida num card de 400 px.",[53,382,383,388,394,396],{},[71,384,385],{},[28,386,387],{},"Fontes e logos",[71,389,390,393],{},[28,391,392],{},"17–85 KB"," cada",[71,395,317],{},[71,397,398,399,402],{},"Servidos sem ",[244,400,401],{},"Cache-Control",".",[53,404,405,412,417,420],{},[71,406,407],{},[28,408,409],{},[244,410,411],{},"/robots.txt",[71,413,414],{},[28,415,416],{},"67 KB",[71,418,419],{},"—",[71,421,422],{},"Devolvia o HTML da SPA. O crawler pedia regras e recebia uma página.",[53,424,425,430,436,438],{},[71,426,427],{},[28,428,429],{},"Sprite de ícones",[71,431,432,435],{},[28,433,434],{},"238 KB"," SVG",[71,437,419],{},[71,439,440],{},"Montado no DOM de toda página pública, dentro do bundle JS.",[53,442,443,450,455,457],{},[71,444,445],{},[28,446,447],{},[244,448,449],{},"\u003Clink rel=\"prefetch\">",[71,451,452],{},[28,453,454],{},"158 links",[71,456,419],{},[71,458,459],{},"Um por chunk do build, disputando banda com o que a página precisava agora.",[16,461,462],{},"Cada linha dessa tabela traduzia uma auditoria genérica em algo concreto. E a primeira linha explicava sozinha boa parte do peso.",[218,464],{},[221,466,468],{"id":467},"problema-1-meio-megabyte-de-css-escondido-no-html","Problema 1: meio megabyte de CSS escondido no HTML",[16,470,471,472,475,476,479,480,483,484,487],{},"O módulo do PrimeVue para Nuxt tem uma opção, ligada por padrão, que pré-injeta no ",[244,473,474],{},"\u003Chead>"," o CSS do tema de cada componente. Sem uma lista explícita dos componentes que o app realmente utiliza, ele injeta ",[28,477,478],{},"todos"," — autocomplete, cascadeselect, treetable, terminal, dock, organograma… componentes que a vitrine nunca renderizou. Eram 184 blocos ",[244,481,482],{},"\u003Cstyle>",", totalizando 462 KB em ",[28,485,486],{},"toda"," resposta HTML, para uma SPA cujo HTML não tinha conteúdo nenhum a estilizar.",[16,489,490,491,494,495,498],{},"Isso é o pior tipo de peso: não cacheia (é o próprio HTML), precisa ser baixado e processado antes de qualquer renderização, e não aparece de forma clara no Lighthouse — o relatório computava como ",[262,492,493],{},"\"JavaScript não usado\""," e ",[262,496,497],{},"\"JavaScript não minificado\"",", pois o mesmo CSS existia como strings dentro do bundle JS.",[16,500,501,502,505,506,402],{},"A correção inicial foi desligar a injeção global (",[244,503,504],{},"loadStyles: false",") e declarar apenas os componentes realmente usados. O HTML caiu de 501 KB para ",[28,507,508],{},"10 KB",[16,510,511],{},"Mais tarde, quando a vitrine migrou para SSR, a injeção voltou a ser feita de forma seletiva — apenas para os ~12 componentes que a vitrine renderiza na resposta inicial. O painel administrativo continua como SPA e injeta o CSS em runtime conforme necessário.",[218,513],{},[221,515,517],{"id":516},"problema-2-o-lcp-era-um-fundo-css-atrás-de-três-idas-e-voltas","Problema 2: o LCP era um fundo CSS atrás de três idas e voltas",[16,519,520,521,523,524,527],{},"O maior elemento visível da home é a foto do hero. Ela estava definida como ",[244,522,360],{}," em uma ",[244,525,526],{},"\u003Cdiv>",". Para o navegador descobrir que precisava dessa imagem, a cadeia de dependências era longa:",[529,530,531,535,538,545,548,551],"ol",{},[532,533,534],"li",{},"Baixar e parsear o HTML.",[532,536,537],{},"Baixar e executar o JS da aplicação.",[532,539,540,541,544],{},"Aguardar o retorno da API da home (",[244,542,543],{},"await"," bloqueante no setup).",[532,546,547],{},"Montar a árvore do DOM.",[532,549,550],{},"Aplicar as regras de CSS para identificar a URL da imagem.",[532,552,553],{},"Iniciar o download de um JPEG de 359 KB.",[16,555,556],{},"Em redes 4G lentas com RTT de ~150 ms, o hero só começava a baixar após quase 4 segundos.",[558,559,561],"h3",{"id":560},"as-correções","As correções:",[563,564,565,586,592],"ul",{},[532,566,567,577,578,581,582,585],{},[28,568,569,572,573,576],{},[244,570,571],{},"\u003Cimg>"," nativo com ",[244,574,575],{},"fetchpriority=\"high\"",":"," Permite que o ",[262,579,580],{},"preload scanner"," do navegador identifique e solicite a imagem imediatamente ao receber o HTML. Adicionamos ",[244,583,584],{},"srcset"," responsivo (800/1200/1600 px), reduzindo o download inicial em celulares para apenas 34 KB.",[532,587,588,591],{},[28,589,590],{},"Conversão para WebP de 1600 px:"," Redução de 359 KB para 98 KB sem perda de qualidade perceptível.",[532,593,594,597,598,601],{},[28,595,596],{},"Desbloqueio da API:"," O hero e a barra de busca tornaram-se estáticos na renderização inicial; a busca por destaques mudou para ",[244,599,600],{},"useLazyFetch"," com esqueletos de carregamento.",[218,603],{},[221,605,607],{"id":606},"problema-3-fotos-gigantes-em-cards-pequenos-e-cache-curto","Problema 3: fotos gigantes em cards pequenos e cache curto",[16,609,610],{},"No fluxo de cadastro, o upload comprimia as imagens para WebP com 2000 px de largura. Excelente para a galeria detalhada do imóvel, mas excessivo para os cards da home, que exibem a imagem em um container de 400 px. Eram cerca de 500 KB por card, multiplicados por 6 destaques na página inicial.",[16,612,613,614,617,618,621],{},"Além disso, o Supabase Storage retornava os objetos com o cabeçalho ",[244,615,616],{},"Cache-Control: max-age=3600"," (4 horas). Ajustamos para um cache imutável de 1 ano (",[244,619,620],{},"max-age=31536000, immutable",") via Cloudflare e headers de origem.",[623,624,625],"blockquote",{},[16,626,627,630,631,634],{},[28,628,629],{},"E se precisarmos alterar uma imagem existente?"," Aplicamos a estratégia padrão de ",[28,632,633],{},"Cache Busting",": quando uma foto é substituída ou atualizada, seu nome ou versão na URL é alterado (por exemplo, adicionando uma hash ou número de versão no caminho). Como a URL muda, o navegador reconhece o recurso como um novo arquivo e baixa a versão atualizada imediatamente, contornando o cache de 1 ano sem qualquer atrito.",[16,636,637,638,494,641,644,645,647],{},"As dimensões de cada imagem também passaram a ser enviadas no DTO da API, alimentando os atributos ",[244,639,640],{},"width",[244,642,643],{},"height"," da tag ",[244,646,571],{},", eliminando qualquer risco de layout shift.",[218,649],{},[221,651,653],{"id":652},"problema-4-o-acúmulo-de-pequenos-detalhes","Problema 4: o acúmulo de pequenos detalhes",[16,655,656],{},"Individualmente, pequenos gargalos parecem inofensivos; acumulados, representavam centenas de kilobytes e dezenas de ms de bloqueio:",[563,658,659,672,685,701,720,737],{},[532,660,661,664,665,667,668,671],{},[28,662,663],{},"Arquivos estáticos sem cache:"," O servidor Nitro não adicionava ",[244,666,401],{}," nos arquivos de ",[244,669,670],{},"public/",". Configuramos regras de roteamento: fontes com cache imutável de 1 ano, imagens estáticas e ícones com 30 dias.",[532,673,674,677,678,680,681,684],{},[28,675,676],{},"158 prefetches desnecessários:"," O Nuxt gerava ",[244,679,449],{}," para todos os chunks assíncronos do build. Removemos esse comportamento via hook no manifest do build. O prefetch passou a ocorrer dinamicamente apenas quando um ",[244,682,683],{},"\u003CNuxtLink>"," entra na viewport.",[532,686,687,690,691,694,695,697,698,402],{},[28,688,689],{},"Sprite SVG de 238 KB:"," Os ícones da ficha técnica estavam agrupados em um componente Vue gigante com todos os ",[244,692,693],{},"\u003Csymbol>"," inline. O sprite foi extraído para um arquivo SVG estático em ",[244,696,670],{},", otimizado via SVGO (metade do tamanho) e referenciado via ",[244,699,700],{},"\u003Cuse href=\"/icons/sprite.svg#nome\">",[532,702,703,709,710,713,714,494,717,402],{},[28,704,705,706,576],{},"Fonte de ícones com ",[244,707,708],{},"font-display: block"," Substituída por hospedagem local do arquivo ",[244,711,712],{},".woff2"," com ",[244,715,716],{},"font-display: swap",[244,718,719],{},"\u003Clink rel=\"preload\">",[532,721,722,725,726,729,730,732,733,736],{},[28,723,724],{},"Acessibilidade e SEO:"," Correção de botões sem rótulo acessível (",[244,727,728],{},"aria-label","), ajuste da hierarquia de cabeçalhos (",[244,731,221],{}," a ",[244,734,735],{},"h4","), meta tags de SEO e ajuste de contraste no tom de verde da marca para atingir o mínimo de 4,5:1.",[532,738,739,742,743,265,746,265,749,752],{},[28,740,741],{},"Headers de segurança:"," Adição de HSTS, ",[244,744,745],{},"X-Frame-Options",[244,747,748],{},"X-Content-Type-Options",[244,750,751],{},"Referrer-Policy"," e COOP.",[218,754],{},[221,756,758],{"id":757},"a-virada-ssr-seletivo-onde-realmente-importa","A virada: SSR seletivo onde realmente importa",[16,760,761,762,765],{},"Com o aplicativo ajustado, veio a decisão de arquitetura crucial: ",[28,763,764],{},"adotar Server-Side Rendering (SSR)"," para a vitrine pública.",[16,767,768,769,772],{},"O principal motivo não foi apenas o LCP, mas a ",[28,770,771],{},"experiência de compartilhamento",". Quando um corretor ou cliente enviava o link de um imóvel no WhatsApp ou redes sociais, o resultado era um card genérico sem foto, preço ou título. Como os bot de prévia não executam JavaScript, a SPA entregava uma página em branco.",[16,774,775,776,779],{},"Utilizando o ",[244,777,778],{},"routeRules"," do Nuxt, configuramos a aplicação de forma híbrida:",[563,781,782,788],{},[532,783,784,787],{},[28,785,786],{},"SSR por padrão:"," Para a home, busca, landing pages e páginas de imóveis.",[532,789,790,795,796,799],{},[28,791,792,794],{},[244,793,246],{}," (SPA):"," Para o painel administrativo, telas de autenticação e a página de favoritos (que depende exclusivamente de ",[244,797,798],{},"localStorage",").",[801,802,807],"pre",{"className":803,"code":804,"language":805,"meta":806,"style":806},"language-typescript shiki shiki-themes github-light github-dark","// sample\nexport default defineNuxtConfig({\n  routeRules: {\n    '/dashboard/**': { ssr: false },\n    '/checkout': { ssr: false },\n    '/catalog/**': { swr: 3600 }\n  }\n})\n","typescript","",[244,808,809,818,836,842,859,871,886,892],{"__ignoreMap":806},[810,811,814],"span",{"class":812,"line":813},"line",1,[810,815,817],{"class":816},"sJ8bj","// sample\n",[810,819,821,825,828,832],{"class":812,"line":820},2,[810,822,824],{"class":823},"szBVR","export",[810,826,827],{"class":823}," default",[810,829,831],{"class":830},"sScJk"," defineNuxtConfig",[810,833,835],{"class":834},"sVt8B","({\n",[810,837,839],{"class":812,"line":838},3,[810,840,841],{"class":834},"  routeRules: {\n",[810,843,845,849,852,856],{"class":812,"line":844},4,[810,846,848],{"class":847},"sZZnC","    '/dashboard/**'",[810,850,851],{"class":834},": { ssr: ",[810,853,855],{"class":854},"sj4cs","false",[810,857,858],{"class":834}," },\n",[810,860,862,865,867,869],{"class":812,"line":861},5,[810,863,864],{"class":847},"    '/checkout'",[810,866,851],{"class":834},[810,868,855],{"class":854},[810,870,858],{"class":834},[810,872,874,877,880,883],{"class":812,"line":873},6,[810,875,876],{"class":847},"    '/catalog/**'",[810,878,879],{"class":834},": { swr: ",[810,881,882],{"class":854},"3600",[810,884,885],{"class":834}," }\n",[810,887,889],{"class":812,"line":888},7,[810,890,891],{"class":834},"  }\n",[810,893,895],{"class":812,"line":894},8,[810,896,897],{"class":834},"})\n",[558,899,901],{"id":900},"cuidados-indispensáveis-ao-introduzir-ssr","Cuidados indispensáveis ao introduzir SSR:",[529,903,904,917,930],{},[532,905,906,909,910,912,913,916],{},[28,907,908],{},"Hydration Mismatches:"," Garantimos que a leitura de ",[244,911,798],{}," e operações não determinísticas (como ordenação aleatória) ocorram apenas no hook ",[244,914,915],{},"onMounted",", evitando divergências entre o HTML gerado no servidor e o DOM do cliente.",[532,918,919,922,923,926,927,402],{},[28,920,921],{},"Reatividade no Servidor:"," Substituição de ",[244,924,925],{},"watch"," que preenchia listas após fetches por propriedades ",[244,928,929],{},"computed",[532,931,932,935,936,494,939,942,943,402],{},[28,933,934],{},"Serviços Globais do PrimeVue:"," Manutenção explícita dos componentes ",[244,937,938],{},"\u003CToast />",[244,940,941],{},"\u003CConfirmDialog />"," para garantir o registro dos serviços injetados via ",[244,944,945],{},"useToast()",[218,947],{},[221,949,951],{"id":950},"otimizações-de-compressão-e-bundling-na-entrega","Otimizações de compressão e bundling na entrega",[16,953,954],{},"Para garantir que o ganho estivesse consolidado do servidor até o cliente, aplicamos otimizações adicionais no pipeline do Nitro e Rollup:",[563,956,957,966,972],{},[532,958,959,962,963,402],{},[28,960,961],{},"Compressão Brotli no SSR:"," Adicionamos um plugin no Nitro para comprimir o HTML diretamente com Brotli/Gzip antes de enviar ao proxy. O HTML enviado passou de 196 KB para ",[28,964,965],{},"24 KB",[532,967,968,971],{},[28,969,970],{},"Consolidação de Chunks (Rollup):"," Originalmente, o build gerava 101 chunks JS (74 deles com menos de 10 KB). Ajustamos o agrupamento do Rollup para fundir pequenos arquivos sem comprometer o code-splitting. O total de chunks caiu de 101 para 71, e a home passou a solicitar apenas 19 arquivos JS em vez de 44.",[532,973,974,977,978,981,982,985],{},[28,975,976],{},"Preload prioritário do Hero:"," Injeção do header HTTP ",[244,979,980],{},"Link: rel=preload"," com suporte a ",[244,983,984],{},"imagesrcset"," para colocar a imagem principal no topo da fila de rede antes de qualquer outro recurso.",[218,987],{},[221,989,991],{"id":990},"o-que-aprendemos","O que aprendemos",[529,993,994,1003,1009,1015],{},[532,995,996,999,1000,1002],{},[28,997,998],{},"Meça o tráfego real com dados brutos:"," Relatórios automatizados dão o ponto de partida, mas inspeções com ",[244,1001,256],{}," e análise de headers revelam onde estão os megabytes ocultos.",[532,1004,1005,1008],{},[28,1006,1007],{},"SSR na vitrine é sobre conversão:"," Prévia correta no WhatsApp e indexação em buscadores são requisitos de negócio, não apenas métricas técnicas.",[532,1010,1011,1014],{},[28,1012,1013],{},"Cuidado com a hidratação:"," Qualquer estado dependente do navegador deve nascer neutro no servidor e ser hidratado após a montagem do componente.",[532,1016,1017,1020],{},[28,1018,1019],{},"Gerenciamento de dependências de UI:"," Módulos de componentes de interface devem ser configurados para incluir apenas o CSS e os scripts estritamente utilizados no caminho crítico.",[218,1022],{},[221,1024,1026],{"id":1025},"resumo-em-uma-frase","Resumo em uma frase",[16,1028,1029,1030,1032,1033,402],{},"Transformamos uma SPA que entregava 500 KB de CSS inline em uma aplicação SSR com HTML comprimido em 24 KB, imagem principal pré-carregada e cards com suporte total a previews sociais — elevando a nota no Lighthouse de ",[28,1031,30],{}," e reduzindo o LCP de ",[28,1034,34],{},[1036,1037,1038],"style",{},"html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":806,"searchDepth":820,"depth":820,"links":1040},[1041,1042,1044,1045,1048,1049,1050,1053,1054,1055],{"id":223,"depth":820,"text":224},{"id":252,"depth":820,"text":1043},"O relatório dizia pouco. O curl disse tudo.",{"id":467,"depth":820,"text":468},{"id":516,"depth":820,"text":517,"children":1046},[1047],{"id":560,"depth":838,"text":561},{"id":606,"depth":820,"text":607},{"id":652,"depth":820,"text":653},{"id":757,"depth":820,"text":758,"children":1051},[1052],{"id":900,"depth":838,"text":901},{"id":950,"depth":820,"text":951},{"id":990,"depth":820,"text":991},{"id":1025,"depth":820,"text":1026},"2026-09-18","Como ajustei o LCP de 6,8s para 2,0s e a nota de performance do Nuxt 4 De 66 a 97 corrigindo CSS inline, SSR seletivo, imagens e cache.","md",true,{},"/blog/de-69-a-97-no-lighthouse",{"title":7,"description":1057},"blog/de-69-a-97-no-lighthouse",[1065,1066,1067,1068,1069],"Nuxt","Web Performance","Lighthouse","SSR","Core Web Vitals","c32YhHvI09aC-MITnkxNcfXAK-fGqntNeekO2dUnh9Q","pt-BR",false,1789775732472]