[{"data":1,"prerenderedAt":910},["ShallowReactive",2],{"blog-nuxt-performance-optimisation":3},{"id":4,"title":5,"body":6,"coverImage":895,"description":896,"extension":897,"meta":898,"navigation":442,"path":899,"published":442,"publishedAt":900,"readTime":901,"seo":902,"stem":903,"tags":904,"__hash__":909},"blog\u002Fblog\u002Fnuxt-performance-optimisation.md","Optimiser les performances d'une application Nuxt sans complexifier le projet",{"type":7,"value":8,"toc":881},"minimark",[9,14,18,21,24,47,51,54,57,83,86,90,98,212,215,238,241,245,248,334,340,354,357,361,364,404,411,478,481,495,498,502,505,605,608,622,629,632,636,639,708,711,729,732,736,739,742,756,759,763,766,769,786,807,810,814,817,837,840,844,847,864,867,871,874,877],[10,11,13],"h2",{"id":12},"pourquoi-les-performances-comptent","Pourquoi les performances comptent",[15,16,17],"p",{},"Une application lente fait perdre des utilisateurs, mais elle fait aussi perdre en visibilité. Les performances influencent directement l'expérience utilisateur et, dans une certaine mesure, le référencement.",[15,19,20],{},"Quand une page met trop de temps à s'afficher, l'utilisateur n'attend pas toujours. Il ferme l'onglet, revient en arrière ou se tourne vers un concurrent. L'objectif de l'optimisation n'est donc pas d'obtenir un score artificiel : c'est de rendre l'application réellement plus agréable et plus fiable.",[15,22,23],{},"Les métriques à suivre en priorité sont les Core Web Vitals :",[25,26,27,35,41],"ul",{},[28,29,30,34],"li",{},[31,32,33],"strong",{},"LCP"," : le contenu principal doit apparaître rapidement",[28,36,37,40],{},[31,38,39],{},"INP"," : les interactions doivent rester fluides",[28,42,43,46],{},[31,44,45],{},"CLS"," : la page ne doit pas bouger de manière imprévisible",[10,48,50],{"id":49},"avant-doptimiser-choisissez-le-bon-mode-de-rendu","Avant d'optimiser, choisissez le bon mode de rendu",[15,52,53],{},"Nuxt permet de choisir le mode de rendu route par route. C'est l'un de ses plus gros avantages, car toutes les pages n'ont pas les mêmes besoins.",[15,55,56],{},"Quelques repères simples :",[25,58,59,65,71,77],{},[28,60,61,64],{},[31,62,63],{},"prerender \u002F SSG"," pour les pages très stables comme l'accueil ou les pages marketing",[28,66,67,70],{},[31,68,69],{},"SSR"," pour les pages qui doivent afficher des données fraîches dès le premier chargement",[28,72,73,76],{},[31,74,75],{},"ISR"," pour les pages qui peuvent être régénérées périodiquement",[28,78,79,82],{},[31,80,81],{},"SPA"," pour certaines zones privées ou très interactives",[15,84,85],{},"Le plus important est d'éviter une règle unique pour tout le site.",[10,87,89],{"id":88},"_1-choisir-la-bonne-stratégie-de-rendu","1. Choisir la bonne stratégie de rendu",[15,91,92,93,97],{},"Nuxt propose plusieurs modes selon la nature de vos pages. Définissez-les précisément avec ",[94,95,96],"code",{},"routeRules"," pour ne pas rendre tout votre site plus lourd que nécessaire.",[99,100,105],"pre",{"className":101,"code":102,"language":103,"meta":104,"style":104},"language-typescript shiki shiki-themes github-light github-dark","\u002F\u002F nuxt.config.ts\nexport default defineNuxtConfig({\n  routeRules: {\n    '\u002F': { prerender: true },\n    '\u002Fblog\u002F**': { isr: 3600 },\n    '\u002Fdashboard\u002F**': { ssr: false },\n    '\u002Fapi\u002F**': { cache: { maxAge: 60 } },\n  },\n})\n","typescript","",[94,106,107,116,134,140,157,171,185,200,206],{"__ignoreMap":104},[108,109,112],"span",{"class":110,"line":111},"line",1,[108,113,115],{"class":114},"sJ8bj","\u002F\u002F nuxt.config.ts\n",[108,117,119,123,126,130],{"class":110,"line":118},2,[108,120,122],{"class":121},"szBVR","export",[108,124,125],{"class":121}," default",[108,127,129],{"class":128},"sScJk"," defineNuxtConfig",[108,131,133],{"class":132},"sVt8B","({\n",[108,135,137],{"class":110,"line":136},3,[108,138,139],{"class":132},"  routeRules: {\n",[108,141,143,147,150,154],{"class":110,"line":142},4,[108,144,146],{"class":145},"sZZnC","    '\u002F'",[108,148,149],{"class":132},": { prerender: ",[108,151,153],{"class":152},"sj4cs","true",[108,155,156],{"class":132}," },\n",[108,158,160,163,166,169],{"class":110,"line":159},5,[108,161,162],{"class":145},"    '\u002Fblog\u002F**'",[108,164,165],{"class":132},": { isr: ",[108,167,168],{"class":152},"3600",[108,170,156],{"class":132},[108,172,174,177,180,183],{"class":110,"line":173},6,[108,175,176],{"class":145},"    '\u002Fdashboard\u002F**'",[108,178,179],{"class":132},": { ssr: ",[108,181,182],{"class":152},"false",[108,184,156],{"class":132},[108,186,188,191,194,197],{"class":110,"line":187},7,[108,189,190],{"class":145},"    '\u002Fapi\u002F**'",[108,192,193],{"class":132},": { cache: { maxAge: ",[108,195,196],{"class":152},"60",[108,198,199],{"class":132}," } },\n",[108,201,203],{"class":110,"line":202},8,[108,204,205],{"class":132},"  },\n",[108,207,209],{"class":110,"line":208},9,[108,210,211],{"class":132},"})\n",[15,213,214],{},"En pratique :",[25,216,217,223,229,235],{},[28,218,219,222],{},[94,220,221],{},"prerender"," convient très bien aux pages statiques",[28,224,225,228],{},[94,226,227],{},"isr"," évite de reconstruire tout le site pour une simple mise à jour",[28,230,231,234],{},[94,232,233],{},"ssr: false"," peut être utile pour une zone d'administration riche en interactions",[28,236,237],{},"le cache API réduit la charge serveur et accélère les réponses répétées",[15,239,240],{},"Cette décision initiale a souvent plus d'impact que beaucoup d'autres micro-optimisations.",[10,242,244],{"id":243},"_2-optimiser-les-images-avec-nuxtimage","2. Optimiser les images avec @nuxt\u002Fimage",[15,246,247],{},"Les images sont l'une des premières causes de lenteur. Une image trop lourde peut ruiner un bon travail sur le reste de la page.",[99,249,253],{"className":250,"code":251,"language":252,"meta":104,"style":104},"language-ts shiki shiki-themes github-light github-dark","const image = {\n  src: '\u002Fphoto.jpeg',\n  width: 400,\n  height: 400,\n  format: 'webp',\n  loading: 'lazy',\n  sizes: 'sm:100vw md:50vw lg:400px',\n}\n","ts",[94,254,255,269,280,290,299,309,319,329],{"__ignoreMap":104},[108,256,257,260,263,266],{"class":110,"line":111},[108,258,259],{"class":121},"const",[108,261,262],{"class":152}," image",[108,264,265],{"class":121}," =",[108,267,268],{"class":132}," {\n",[108,270,271,274,277],{"class":110,"line":118},[108,272,273],{"class":132},"  src: ",[108,275,276],{"class":145},"'\u002Fphoto.jpeg'",[108,278,279],{"class":132},",\n",[108,281,282,285,288],{"class":110,"line":136},[108,283,284],{"class":132},"  width: ",[108,286,287],{"class":152},"400",[108,289,279],{"class":132},[108,291,292,295,297],{"class":110,"line":142},[108,293,294],{"class":132},"  height: ",[108,296,287],{"class":152},[108,298,279],{"class":132},[108,300,301,304,307],{"class":110,"line":159},[108,302,303],{"class":132},"  format: ",[108,305,306],{"class":145},"'webp'",[108,308,279],{"class":132},[108,310,311,314,317],{"class":110,"line":173},[108,312,313],{"class":132},"  loading: ",[108,315,316],{"class":145},"'lazy'",[108,318,279],{"class":132},[108,320,321,324,327],{"class":110,"line":187},[108,322,323],{"class":132},"  sizes: ",[108,325,326],{"class":145},"'sm:100vw md:50vw lg:400px'",[108,328,279],{"class":132},[108,330,331],{"class":110,"line":202},[108,332,333],{"class":132},"}\n",[15,335,336,339],{},[94,337,338],{},"@nuxt\u002Fimage"," apporte plusieurs bénéfices à la fois :",[25,341,342,345,348,351],{},[28,343,344],{},"génération automatique des tailles adaptées",[28,346,347],{},"formats modernes comme WebP ou AVIF selon la configuration",[28,349,350],{},"chargement différé des images hors écran",[28,352,353],{},"réduction du poids transféré au navigateur",[15,355,356],{},"Le bon réflexe est simple : ne servez jamais une image plus grande que nécessaire. Une image de 2500 pixels affichée dans un bloc de 400 pixels gaspille du temps et de la bande passante.",[10,358,360],{"id":359},"_3-code-splitting-et-imports-dynamiques","3. Code splitting et imports dynamiques",[15,362,363],{},"Plus une page charge de JavaScript, plus elle met du temps à devenir interactive. Il est donc utile de charger certains composants uniquement quand ils sont réellement nécessaires.",[99,365,367],{"className":101,"code":366,"language":103,"meta":104,"style":104},"\u002F\u002F Ne charger un composant que quand il est visible\nconst HeavyChart = defineAsyncComponent(() => import('~\u002Fcomponents\u002FHeavyChart.vue'))\n",[94,368,369,374],{"__ignoreMap":104},[108,370,371],{"class":110,"line":111},[108,372,373],{"class":114},"\u002F\u002F Ne charger un composant que quand il est visible\n",[108,375,376,378,381,383,386,389,392,395,398,401],{"class":110,"line":118},[108,377,259],{"class":121},[108,379,380],{"class":152}," HeavyChart",[108,382,265],{"class":121},[108,384,385],{"class":128}," defineAsyncComponent",[108,387,388],{"class":132},"(() ",[108,390,391],{"class":121},"=>",[108,393,394],{"class":121}," import",[108,396,397],{"class":132},"(",[108,399,400],{"class":145},"'~\u002Fcomponents\u002FHeavyChart.vue'",[108,402,403],{"class":132},"))\n",[15,405,406,407,410],{},"Pour les composants utilisés uniquement côté client, combinez cela avec ",[94,408,409],{},"ClientOnly"," :",[99,412,414],{"className":250,"code":413,"language":252,"meta":104,"style":104},"const HeavyChart = defineAsyncComponent(() => import('~\u002Fcomponents\u002FHeavyChart.vue'))\n\nconst chartStrategy = {\n  ssr: false,\n  fallback: 'skeleton h-48',\n}\n",[94,415,416,438,444,455,464,474],{"__ignoreMap":104},[108,417,418,420,422,424,426,428,430,432,434,436],{"class":110,"line":111},[108,419,259],{"class":121},[108,421,380],{"class":152},[108,423,265],{"class":121},[108,425,385],{"class":128},[108,427,388],{"class":132},[108,429,391],{"class":121},[108,431,394],{"class":121},[108,433,397],{"class":132},[108,435,400],{"class":145},[108,437,403],{"class":132},[108,439,440],{"class":110,"line":118},[108,441,443],{"emptyLinePlaceholder":442},true,"\n",[108,445,446,448,451,453],{"class":110,"line":136},[108,447,259],{"class":121},[108,449,450],{"class":152}," chartStrategy",[108,452,265],{"class":121},[108,454,268],{"class":132},[108,456,457,460,462],{"class":110,"line":142},[108,458,459],{"class":132},"  ssr: ",[108,461,182],{"class":152},[108,463,279],{"class":132},[108,465,466,469,472],{"class":110,"line":159},[108,467,468],{"class":132},"  fallback: ",[108,470,471],{"class":145},"'skeleton h-48'",[108,473,279],{"class":132},[108,475,476],{"class":110,"line":173},[108,477,333],{"class":132},[15,479,480],{},"Cette stratégie est particulièrement utile pour :",[25,482,483,486,489,492],{},[28,484,485],{},"les graphiques lourds",[28,487,488],{},"les éditeurs de texte riches",[28,490,491],{},"les cartes interactives",[28,493,494],{},"les composants qui dépendent du navigateur",[15,496,497],{},"Le but est de ne pas bloquer l'affichage de la page avec du code qui n'est pas indispensable au premier rendu.",[10,499,501],{"id":500},"_4-caching-des-requêtes-serveur","4. Caching des requêtes serveur",[15,503,504],{},"Si votre application appelle souvent les mêmes données, le cache peut faire une énorme différence. Inutile de recalculer ou de refetch les mêmes informations à chaque requête si elles changent rarement.",[99,506,508],{"className":101,"code":507,"language":103,"meta":104,"style":104},"\u002F\u002F server\u002Fapi\u002Fportfolio.get.ts\nexport default defineCachedEventHandler(async (event) => {\n  return await fetchPortfolioData()\n}, {\n  maxAge: 60 * 60,\n  swr: true,\n  getKey: () => 'portfolio',\n})\n",[94,509,510,515,543,557,562,577,586,601],{"__ignoreMap":104},[108,511,512],{"class":110,"line":111},[108,513,514],{"class":114},"\u002F\u002F server\u002Fapi\u002Fportfolio.get.ts\n",[108,516,517,519,521,524,526,529,532,536,539,541],{"class":110,"line":118},[108,518,122],{"class":121},[108,520,125],{"class":121},[108,522,523],{"class":128}," defineCachedEventHandler",[108,525,397],{"class":132},[108,527,528],{"class":121},"async",[108,530,531],{"class":132}," (",[108,533,535],{"class":534},"s4XuR","event",[108,537,538],{"class":132},") ",[108,540,391],{"class":121},[108,542,268],{"class":132},[108,544,545,548,551,554],{"class":110,"line":136},[108,546,547],{"class":121},"  return",[108,549,550],{"class":121}," await",[108,552,553],{"class":128}," fetchPortfolioData",[108,555,556],{"class":132},"()\n",[108,558,559],{"class":110,"line":142},[108,560,561],{"class":132},"}, {\n",[108,563,564,567,569,572,575],{"class":110,"line":159},[108,565,566],{"class":132},"  maxAge: ",[108,568,196],{"class":152},[108,570,571],{"class":121}," *",[108,573,574],{"class":152}," 60",[108,576,279],{"class":132},[108,578,579,582,584],{"class":110,"line":173},[108,580,581],{"class":132},"  swr: ",[108,583,153],{"class":152},[108,585,279],{"class":132},[108,587,588,591,594,596,599],{"class":110,"line":187},[108,589,590],{"class":128},"  getKey",[108,592,593],{"class":132},": () ",[108,595,391],{"class":121},[108,597,598],{"class":145}," 'portfolio'",[108,600,279],{"class":132},[108,602,603],{"class":110,"line":202},[108,604,211],{"class":132},[15,606,607],{},"Ce pattern est particulièrement intéressant pour :",[25,609,610,613,616,619],{},[28,611,612],{},"des pages de portfolio",[28,614,615],{},"des listes d'articles",[28,617,618],{},"des contenus qui changent peu",[28,620,621],{},"des réponses d'API coûteuses à produire",[15,623,624,625,628],{},"Le mode ",[94,626,627],{},"stale-while-revalidate"," est très utile, car il permet de servir une version rapide tout en régénérant les données en arrière-plan.",[15,630,631],{},"Vous pouvez également cacher côté client quand cela a du sens, mais la première vraie économie de temps se fait souvent côté serveur.",[10,633,635],{"id":634},"_5-payload-et-compression","5. Payload et compression",[15,637,638],{},"Nuxt peut aussi vous aider à réduire le poids global de la page générée. Moins vous envoyez de données inutiles, plus le chargement est rapide.",[99,640,642],{"className":101,"code":641,"language":103,"meta":104,"style":104},"\u002F\u002F nuxt.config.ts\nexport default defineNuxtConfig({\n  nitro: {\n    compressPublicAssets: true,\n    minify: true,\n  },\n  experimental: {\n    payloadExtraction: true,\n  },\n})\n",[94,643,644,648,658,663,672,681,685,690,699,703],{"__ignoreMap":104},[108,645,646],{"class":110,"line":111},[108,647,115],{"class":114},[108,649,650,652,654,656],{"class":110,"line":118},[108,651,122],{"class":121},[108,653,125],{"class":121},[108,655,129],{"class":128},[108,657,133],{"class":132},[108,659,660],{"class":110,"line":136},[108,661,662],{"class":132},"  nitro: {\n",[108,664,665,668,670],{"class":110,"line":142},[108,666,667],{"class":132},"    compressPublicAssets: ",[108,669,153],{"class":152},[108,671,279],{"class":132},[108,673,674,677,679],{"class":110,"line":159},[108,675,676],{"class":132},"    minify: ",[108,678,153],{"class":152},[108,680,279],{"class":132},[108,682,683],{"class":110,"line":173},[108,684,205],{"class":132},[108,686,687],{"class":110,"line":187},[108,688,689],{"class":132},"  experimental: {\n",[108,691,692,695,697],{"class":110,"line":202},[108,693,694],{"class":132},"    payloadExtraction: ",[108,696,153],{"class":152},[108,698,279],{"class":132},[108,700,701],{"class":110,"line":208},[108,702,205],{"class":132},[108,704,706],{"class":110,"line":705},10,[108,707,211],{"class":132},[15,709,710],{},"Quelques bonnes pratiques utiles :",[25,712,713,716,723,726],{},[28,714,715],{},"limitez les données envoyées au client au strict nécessaire",[28,717,718,719,722],{},"évitez de surcharger ",[94,720,721],{},"useAsyncData"," avec des objets trop volumineux",[28,724,725],{},"préférez des réponses API compactes",[28,727,728],{},"supprimez les champs que l'interface n'utilise pas",[15,730,731],{},"Si vous envoyez moins de données, vous gagnez à la fois en temps réseau et en temps de traitement JavaScript.",[10,733,735],{"id":734},"_6-réduire-le-travail-du-navigateur","6. Réduire le travail du navigateur",[15,737,738],{},"Optimiser Nuxt, ce n'est pas seulement réduire le poids du HTML. C'est aussi faire en sorte que le navigateur ait moins de travail à faire après le chargement.",[15,740,741],{},"Quelques leviers simples :",[25,743,744,747,750,753],{},[28,745,746],{},"évitez de multiplier les états locaux inutiles",[28,748,749],{},"ne chargez pas de librairies lourdes pour un usage marginal",[28,751,752],{},"préférez des composants simples quand un composant complexe n'apporte rien",[28,754,755],{},"gardez les calculs coûteux hors du cycle de rendu si possible",[15,757,758],{},"Une page plus simple est souvent une page plus rapide.",[10,760,762],{"id":761},"_7-mesurer-avec-lighthouse","7. Mesurer avec Lighthouse",[15,764,765],{},"Avant d'optimiser, mesurez. Sans mesure, vous risquez d'améliorer une chose invisible et de laisser le vrai problème intact.",[15,767,768],{},"Les indicateurs à surveiller :",[25,770,771,776,781],{},[28,772,773,775],{},[31,774,33],{}," : le plus grand élément visible doit arriver rapidement",[28,777,778,780],{},[31,779,39],{}," : la réactivité doit rester bonne",[28,782,783,785],{},[31,784,45],{}," (Cumulative Layout Shift) : \u003C 0,1",[99,787,791],{"className":788,"code":789,"language":790,"meta":104,"style":104},"language-bash shiki shiki-themes github-light github-dark","npx unlighthouse --site https:\u002F\u002Fmonsite.com\n","bash",[94,792,793],{"__ignoreMap":104},[108,794,795,798,801,804],{"class":110,"line":111},[108,796,797],{"class":128},"npx",[108,799,800],{"class":145}," unlighthouse",[108,802,803],{"class":152}," --site",[108,805,806],{"class":145}," https:\u002F\u002Fmonsite.com\n",[15,808,809],{},"Vous pouvez aussi utiliser Lighthouse, les DevTools du navigateur et les logs serveur pour comprendre où part le temps.",[10,811,813],{"id":812},"une-méthode-simple-pour-prioriser-les-optimisations","Une méthode simple pour prioriser les optimisations",[15,815,816],{},"Si vous ne savez pas par où commencer, avancez dans cet ordre :",[818,819,820,825,828,831,834],"ol",{},[28,821,822,823],{},"choisir le bon mode de rendu avec ",[94,824,96],{},[28,826,827],{},"compresser et alléger les images",[28,829,830],{},"réduire le JavaScript chargé au premier affichage",[28,832,833],{},"mettre en cache les réponses répétées",[28,835,836],{},"mesurer à nouveau pour vérifier le gain réel",[15,838,839],{},"Cette méthode permet d'obtenir des résultats visibles sans disperser l'effort.",[10,841,843],{"id":842},"les-erreurs-fréquentes","Les erreurs fréquentes",[15,845,846],{},"Voici les pièges les plus courants :",[25,848,849,852,855,858,861],{},[28,850,851],{},"tout rendre en SSR sans réfléchir",[28,853,854],{},"charger des images trop lourdes",[28,856,857],{},"utiliser trop de composants client-only",[28,859,860],{},"oublier le cache sur des données statiques",[28,862,863],{},"optimiser sans mesurer",[15,865,866],{},"La performance n'est pas un geste isolé. C'est une suite de petites décisions cohérentes.",[10,868,870],{"id":869},"conclusion","Conclusion",[15,872,873],{},"L'optimisation d'une application Nuxt doit rester pragmatique. Commencez par le mode de rendu, allégez les images, chargez moins de JavaScript et mettez en cache ce qui peut l'être.",[15,875,876],{},"Si vous mesurez après chaque changement, vous saurez exactement ce qui améliore vraiment l'expérience utilisateur. C'est cette discipline qui permet d'avoir une application rapide, propre et durable.",[878,879,880],"style",{},"html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}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);}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 .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}",{"title":104,"searchDepth":118,"depth":118,"links":882},[883,884,885,886,887,888,889,890,891,892,893,894],{"id":12,"depth":118,"text":13},{"id":49,"depth":118,"text":50},{"id":88,"depth":118,"text":89},{"id":243,"depth":118,"text":244},{"id":359,"depth":118,"text":360},{"id":500,"depth":118,"text":501},{"id":634,"depth":118,"text":635},{"id":734,"depth":118,"text":735},{"id":761,"depth":118,"text":762},{"id":812,"depth":118,"text":813},{"id":842,"depth":118,"text":843},{"id":869,"depth":118,"text":870},null,"Un guide pratique pour améliorer les Core Web Vitals d'une application Nuxt avec le bon rendu, des images optimisées, du cache et un chargement plus léger.","md",{},"\u002Fblog\u002Fnuxt-performance-optimisation","2024-12-05",11,{"title":5,"description":896},"blog\u002Fnuxt-performance-optimisation",[905,906,907,908],"Nuxt","Vue.js","Performance","Frontend","Uy80pOh8vB8BN8kaBHhD3ImH5zdbzNBr1BCMtAWgm44",1788219651639]