[{"data":1,"prerenderedAt":929},["ShallowReactive",2],{"content:\u002Fframework-performance\u002Fvue-and-nuxt-performance\u002Flazy-hydration-in-nuxt":3,"surroundings:\u002Fframework-performance\u002Fvue-and-nuxt-performance\u002Flazy-hydration-in-nuxt":920},{"id":4,"title":5,"body":6,"description":900,"extension":901,"meta":902,"navigation":913,"path":914,"seo":915,"stem":918,"__hash__":919},"content\u002Fframework-performance\u002Fvue-and-nuxt-performance\u002Flazy-hydration-in-nuxt\u002Findex.md","Lazy Hydration in Nuxt",{"type":7,"value":8,"toc":881},"minimark",[9,13,28,40,192,197,225,229,235,241,247,253,257,262,399,409,413,420,424,427,431,438,569,573,576,580,583,587,594,598,601,671,675,681,685,711,715,721,727,733,739,743,755,764,773,785,794,803,812,821,830,839,843,866,871,874,877],[10,11,5],"h1",{"id":12},"lazy-hydration-in-nuxt",[14,15,16,17,22,23,27],"p",{},"This guide is part of ",[18,19,21],"a",{"href":20},"\u002Fframework-performance\u002Fvue-and-nuxt-performance\u002F","Vue & Nuxt Performance",", within ",[18,24,26],{"href":25},"\u002Fframework-performance\u002F","Framework Performance",". A server-rendered Nuxt page arrives as complete HTML, but it is not interactive until hydration has run: Vue loads the components' JavaScript, runs their setup, rebuilds state and attaches event listeners. By default, every component on the page hydrates immediately after load — the header, the hero, the product description, the reviews section, the recommendations carousel and the footer — in one burst of main-thread work.",[14,29,30,31,35,36,39],{},"Most of that work is unnecessary at load time. Components below the fold will not be used for seconds, and some (static text, footers) never need interactivity. ",[32,33,34],"strong",{},"Lazy hydration"," delays hydrating a component until a trigger: when it becomes visible, when the browser is idle, when the user interacts with it, after a delay, or when a media query matches. ",[32,37,38],{},"Server components"," go further, rendering on the server with no client JavaScript at all. Together they shrink the hydration burst, reducing TBT and the INP of early interactions.",[14,41,42],{},[43,44,50,51,50,58,50,62,50,65,50,74,50,80,50,91,50,95,50,100,50,108,50,115,50,119,50,125,50,130,50,136,50,140,50,145,50,151,50,155,50,159,50,163,50,167,50,171,50,175,50,179,50,183,50,189,50],"svg",{"viewBox":45,"width":46,"role":47,"ariaLabel":48,"style":49},"0 0 760 200","100%","img","Timeline comparing main-thread hydration work for eager hydration of all components and lazy hydration of below-the-fold components.","height:auto;max-width:760px;display:block;margin:1.75rem auto;font-family:inherit;color:var(--fp-svg-ink)"," ",[52,53],"rect",{"className":54,"x":56,"y":56,"width":46,"height":46,"fill":57},[55],"svg-canvas","0","#ffffff",[59,60,61],"title",{},"Hydration work after load: eager vs lazy",[63,64,48],"desc",{},[52,66],{"x":67,"y":67,"width":68,"height":69,"rx":70,"fill":71,"stroke":72,"style":73},"1","758","198","10","none","currentColor","stroke-opacity:0.18",[75,76,61],"text",{"x":77,"y":78,"fill":72,"style":79},"28.0","34.0","font-size:16px;font-weight:700",[81,82],"line",{"x1":83,"y1":84,"x2":83,"y2":85,"stroke":86,"strokeWidth":87,"strokeDashArray":88,"style":90},"499.1","72.0","156.0","#b8860b","1.5",[89,89],"4","stroke-opacity:0.9",[81,92],{"x1":93,"y1":84,"x2":93,"y2":85,"stroke":86,"strokeWidth":87,"strokeDashArray":94,"style":90},"311.1",[89,89],[75,96,99],{"x":77,"y":97,"fill":72,"style":98},"96.0","font-size:12.5px;font-weight:700","Eager",[52,101],{"x":102,"y":103,"width":104,"height":105,"rx":106,"fill":71,"stroke":72,"style":107},"240.5","78.0","257.8","26.0","3","stroke-opacity:0.35",[75,109,114],{"x":110,"y":111,"fill":72,"style":112,"textAnchor":113},"369.5","95.5","font-size:11.5px","middle","hydrate all components",[75,116,118],{"x":77,"y":117,"fill":72,"style":98},"134.0","Lazy",[52,120],{"x":102,"y":121,"width":122,"height":105,"rx":106,"fill":123,"stroke":86,"style":124},"116.0","69.8","#ffc300","fill-opacity:0.24;stroke-opacity:0.9",[75,126,129],{"x":127,"y":128,"fill":72,"style":112,"textAnchor":113},"275.5","133.5","hero",[52,131],{"x":132,"y":121,"width":133,"height":105,"rx":106,"fill":134,"stroke":134,"style":135},"564.7","63.3","#0466c8","fill-opacity:0.14;stroke-opacity:0.9",[75,137,139],{"x":138,"y":128,"fill":72,"style":112,"textAnchor":113},"596.3","reviews",[81,141],{"x1":142,"y1":85,"x2":143,"y2":85,"stroke":72,"style":144},"77.7","726.0","stroke-opacity:0.4",[75,146,150],{"x":147,"y":148,"fill":149,"style":112,"textAnchor":113},"88.4","173.0","#51617a","0ms",[75,152,154],{"x":153,"y":148,"fill":149,"style":112,"textAnchor":113},"158.8","250ms",[75,156,158],{"x":157,"y":148,"fill":149,"style":112,"textAnchor":113},"239.8","500ms",[75,160,162],{"x":161,"y":148,"fill":149,"style":112,"textAnchor":113},"320.8","750ms",[75,164,166],{"x":165,"y":148,"fill":149,"style":112,"textAnchor":113},"401.9","1000ms",[75,168,170],{"x":169,"y":148,"fill":149,"style":112,"textAnchor":113},"482.9","1250ms",[75,172,174],{"x":173,"y":148,"fill":149,"style":112,"textAnchor":113},"563.9","1500ms",[75,176,178],{"x":177,"y":148,"fill":149,"style":112,"textAnchor":113},"645.0","1750ms",[75,180,182],{"x":181,"y":148,"fill":149,"style":112,"textAnchor":113},"712.3","2000ms",[75,184,188],{"x":93,"y":185,"fill":186,"style":187,"textAnchor":113},"68.0","#8a6608","font-size:12px;font-weight:700","interactive (lazy)",[75,190,191],{"x":83,"y":185,"fill":186,"style":187,"textAnchor":113},"interactive (eager)",[193,194,196],"h2",{"id":195},"rapid-diagnosis","Rapid Diagnosis",[198,199,200,207,213,219],"ul",{},[201,202,203,206],"li",{},[32,204,205],{},"Record a load trace"," with CPU throttling; find the hydration long task after the app bundle runs.",[201,208,209,212],{},[32,210,211],{},"List components on the page"," and mark which are interactive and above the fold.",[201,214,215,218],{},[32,216,217],{},"Check for static content components"," (footers, SEO text, legal blocks) that hydrate.",[201,220,221,224],{},[32,222,223],{},"Check bundle chunks",": below-the-fold components' code should be split out to benefit from lazy hydration.",[193,226,228],{"id":227},"root-cause-analysis","Root Cause Analysis",[14,230,231,234],{},[32,232,233],{},"1. Eager hydration of everything."," All components hydrate at once.",[14,236,237,240],{},[32,238,239],{},"2. Static content as client components."," Components without interactivity still hydrate.",[14,242,243,246],{},[32,244,245],{},"3. Heavy below-the-fold widgets."," Carousels, maps and reviews hydrate during load.",[14,248,249,252],{},[32,250,251],{},"4. Shared chunks."," Lazy components imported statically are still in the main bundle.",[193,254,256],{"id":255},"step-by-step-resolution","Step-by-Step Resolution",[258,259,261],"h3",{"id":260},"_1-use-hydration-triggers-on-lazy-components","1. Use hydration triggers on lazy components",[263,264,269],"pre",{"className":265,"code":266,"language":267,"meta":268,"style":268},"language-html shiki shiki-themes github-light-high-contrast github-dark-high-contrast github-light-high-contrast","\u003Ctemplate>\n  \u003CProductHero :product=\"product\" \u002F>\n  \u003CLazyProductReviews hydrate-on-visible :id=\"product.id\" \u002F>\n  \u003CLazyRecommendations hydrate-on-idle \u002F>\n  \u003CLazyNewsletterSignup hydrate-on-interaction=\"focus\" \u002F>\n  \u003CLazySiteFooter hydrate-never \u002F>\n\u003C\u002Ftemplate>\n\u003C!-- trade-off: before hydration, components are static HTML; clicks on a not-yet-\n     hydrated button do nothing unless the trigger is interaction-based. -->\n","html","",[270,271,272,287,311,332,345,363,376,386,393],"code",{"__ignoreMap":268},[273,274,276,280,284],"span",{"class":81,"line":275},1,[273,277,279],{"class":278},"saISM","\u003C",[273,281,283],{"class":282},"sZBmE","template",[273,285,286],{"class":278},">\n",[273,288,290,293,297,301,304,308],{"class":81,"line":289},2,[273,291,292],{"class":278},"  \u003C",[273,294,296],{"class":295},"si8lv","ProductHero",[273,298,300],{"class":299},"sPXB4"," :product",[273,302,303],{"class":278},"=",[273,305,307],{"class":306},"sZ8jY","\"product\"",[273,309,310],{"class":278}," \u002F>\n",[273,312,314,316,319,322,325,327,330],{"class":81,"line":313},3,[273,315,292],{"class":278},[273,317,318],{"class":295},"LazyProductReviews",[273,320,321],{"class":299}," hydrate-on-visible",[273,323,324],{"class":299}," :id",[273,326,303],{"class":278},[273,328,329],{"class":306},"\"product.id\"",[273,331,310],{"class":278},[273,333,335,337,340,343],{"class":81,"line":334},4,[273,336,292],{"class":278},[273,338,339],{"class":295},"LazyRecommendations",[273,341,342],{"class":299}," hydrate-on-idle",[273,344,310],{"class":278},[273,346,348,350,353,356,358,361],{"class":81,"line":347},5,[273,349,292],{"class":278},[273,351,352],{"class":295},"LazyNewsletterSignup",[273,354,355],{"class":299}," hydrate-on-interaction",[273,357,303],{"class":278},[273,359,360],{"class":306},"\"focus\"",[273,362,310],{"class":278},[273,364,366,368,371,374],{"class":81,"line":365},6,[273,367,292],{"class":278},[273,369,370],{"class":295},"LazySiteFooter",[273,372,373],{"class":299}," hydrate-never",[273,375,310],{"class":278},[273,377,379,382,384],{"class":81,"line":378},7,[273,380,381],{"class":278},"\u003C\u002F",[273,383,283],{"class":282},[273,385,286],{"class":278},[273,387,389],{"class":81,"line":388},8,[273,390,392],{"class":391},"sjfSM","\u003C!-- trade-off: before hydration, components are static HTML; clicks on a not-yet-\n",[273,394,396],{"class":81,"line":395},9,[273,397,398],{"class":391},"     hydrated button do nothing unless the trigger is interaction-based. -->\n",[14,400,401,402,404,405,408],{},"Prefixing a component with ",[270,403,118],{}," splits its code into a separate chunk; the ",[270,406,407],{},"hydrate-*"," props control when it hydrates.",[258,410,412],{"id":411},"_2-make-static-sections-server-components","2. Make static sections server components",[14,414,415,416,419],{},"Rename static components to ",[270,417,418],{},".server.vue"," (with server components enabled) so they render only on the server and ship no client code.",[258,421,423],{"id":422},"_3-choose-triggers-by-component-role","3. Choose triggers by component role",[14,425,426],{},"Visible for below-the-fold sections, interaction for forms and widgets used occasionally, idle for content that should become interactive soon without competing with load, never for static content.",[258,428,430],{"id":429},"_4-reserve-space","4. Reserve space",[14,432,433,434,437],{},"Lazy-hydrated components are server-rendered, so their layout is present; client-only components (",[270,435,436],{},"\u003CClientOnly>",") need sized placeholders to avoid CLS.",[14,439,440],{},[43,441,50,444,50,447,50,450,50,452,50,455,50,457,50,463,50,469,50,473,50,477,50,480,50,484,50,487,50,491,50,493,50,497,50,499,50,502,50,504,50,508,50,510,50,513,50,515,50,518,50,521,50,525,50,527,50,530,50,532,50,535,50,538,50,542,50,544,50,547,50,549,50,552,50,555,50,559,50,561,50,564,50,566,50],{"viewBox":442,"width":46,"role":47,"ariaLabel":443,"style":49},"0 0 760 258","Recommended lazy hydration triggers for common component roles.",[52,445],{"className":446,"x":56,"y":56,"width":46,"height":46,"fill":57},[55],[59,448,449],{},"Choosing a hydration trigger",[63,451,443],{},[52,453],{"x":67,"y":67,"width":68,"height":454,"rx":70,"fill":71,"stroke":72,"style":73},"256",[75,456,449],{"x":77,"y":78,"fill":72,"style":79},[52,458],{"x":77,"y":459,"width":460,"height":461,"rx":56,"fill":72,"stroke":72,"style":462},"56.0","179.4","30.0","fill-opacity:0.06;stroke-opacity:0.4",[75,464,468],{"x":465,"y":466,"fill":72,"style":98,"textAnchor":467},"38.0","75.5","start","Component",[52,470],{"x":471,"y":459,"width":472,"height":461,"rx":56,"fill":72,"stroke":72,"style":462},"207.4","262.3",[75,474,476],{"x":475,"y":466,"fill":72,"style":98,"textAnchor":113},"338.5","Trigger",[52,478],{"x":479,"y":459,"width":472,"height":461,"rx":56,"fill":72,"stroke":72,"style":462},"469.7",[75,481,483],{"x":482,"y":466,"fill":72,"style":98,"textAnchor":113},"600.8","Reason",[52,485],{"x":77,"y":486,"width":460,"height":461,"rx":56,"fill":71,"stroke":72,"style":107},"86.0",[75,488,490],{"x":465,"y":489,"fill":72,"style":98,"textAnchor":467},"105.5","Reviews, recommendations",[52,492],{"x":471,"y":486,"width":472,"height":461,"rx":56,"fill":71,"stroke":72,"style":107},[75,494,496],{"x":475,"y":489,"fill":72,"style":495,"textAnchor":113},"font-size:12px","hydrate-on-visible",[52,498],{"x":479,"y":486,"width":472,"height":461,"rx":56,"fill":71,"stroke":72,"style":107},[75,500,501],{"x":482,"y":489,"fill":72,"style":495,"textAnchor":113},"used after scrolling",[52,503],{"x":77,"y":121,"width":460,"height":461,"rx":56,"fill":71,"stroke":72,"style":107},[75,505,507],{"x":465,"y":506,"fill":72,"style":98,"textAnchor":467},"135.5","Newsletter form",[52,509],{"x":471,"y":121,"width":472,"height":461,"rx":56,"fill":71,"stroke":72,"style":107},[75,511,512],{"x":475,"y":506,"fill":72,"style":495,"textAnchor":113},"hydrate-on-interaction",[52,514],{"x":479,"y":121,"width":472,"height":461,"rx":56,"fill":71,"stroke":72,"style":107},[75,516,517],{"x":482,"y":506,"fill":72,"style":495,"textAnchor":113},"rarely used",[52,519],{"x":77,"y":520,"width":460,"height":461,"rx":56,"fill":71,"stroke":72,"style":107},"146.0",[75,522,524],{"x":465,"y":523,"fill":72,"style":98,"textAnchor":467},"165.5","Chat launcher",[52,526],{"x":471,"y":520,"width":472,"height":461,"rx":56,"fill":71,"stroke":72,"style":107},[75,528,529],{"x":475,"y":523,"fill":72,"style":495,"textAnchor":113},"hydrate-on-idle",[52,531],{"x":479,"y":520,"width":472,"height":461,"rx":56,"fill":71,"stroke":72,"style":107},[75,533,534],{"x":482,"y":523,"fill":72,"style":495,"textAnchor":113},"available soon after load",[52,536],{"x":77,"y":537,"width":460,"height":461,"rx":56,"fill":71,"stroke":72,"style":107},"176.0",[75,539,541],{"x":465,"y":540,"fill":72,"style":98,"textAnchor":467},"195.5","Footer, legal text",[52,543],{"x":471,"y":537,"width":472,"height":461,"rx":56,"fill":71,"stroke":72,"style":107},[75,545,546],{"x":475,"y":540,"fill":72,"style":495,"textAnchor":113},"hydrate-never or .server.vue",[52,548],{"x":479,"y":537,"width":472,"height":461,"rx":56,"fill":71,"stroke":72,"style":107},[75,550,551],{"x":482,"y":540,"fill":72,"style":495,"textAnchor":113},"no interactivity",[52,553],{"x":77,"y":554,"width":460,"height":461,"rx":56,"fill":71,"stroke":72,"style":107},"206.0",[75,556,558],{"x":465,"y":557,"fill":72,"style":98,"textAnchor":467},"225.5","Above-the-fold controls",[52,560],{"x":471,"y":554,"width":472,"height":461,"rx":56,"fill":71,"stroke":72,"style":107},[75,562,563],{"x":475,"y":557,"fill":72,"style":495,"textAnchor":113},"eager",[52,565],{"x":479,"y":554,"width":472,"height":461,"rx":56,"fill":71,"stroke":72,"style":107},[75,567,568],{"x":482,"y":557,"fill":72,"style":495,"textAnchor":113},"needed immediately",[193,570,572],{"id":571},"verification","Verification",[14,574,575],{},"Record a load trace again: the hydration long task should be shorter, with later small tasks as components hydrate on their triggers. Scroll and interact to confirm components hydrate and work. In the field, compare TBT-related metrics and INP for early interactions.",[193,577,579],{"id":578},"worked-example-a-travel-guide-site","Worked Example: A Travel Guide Site",[14,581,582],{},"A travel guide site's destination pages rendered a hero, an article with an interactive table of contents, a photo gallery, a map, a weather widget, reviews, related destinations and a large footer. Hydration took 900ms on a mid-range phone; INP for tapping the table of contents during the first seconds was over 400ms. The team made the article body and footer server components, lazy-hydrated the gallery and map on visibility, the weather widget on idle, and reviews on visibility. The initial hydration task dropped to 220ms, TBT by 650ms, and INP p75 from 290ms to 160ms.",[193,584,586],{"id":585},"how-lazy-hydration-interacts-with-client-navigation","How Lazy Hydration Interacts With Client Navigation",[14,588,589,590,593],{},"On client-side navigation, components render on the client rather than hydrating server HTML. Lazy components still load their code on demand, but hydration triggers apply mainly to the initial server-rendered page. Make sure lazy components render correctly in both modes, and test navigations as well as first loads. Components marked ",[270,591,592],{},"hydrate-never"," still render on client navigation (they have no server HTML to keep), so they should be lightweight or replaced with server components.",[193,595,597],{"id":596},"measuring-the-effect","Measuring the Effect",[14,599,600],{},"Hydration improvements show most clearly in lab traces (shorter initial long task, lower TBT) and in field INP for interactions during the first seconds. Use Long Animation Frames attribution to confirm that hydration frames shrank. Track the number of components hydrated on load as a simple metric in lab tests; it is a good leading indicator before field data catches up.",[14,602,603],{},[43,604,50,607,50,610,50,613,50,615,50,618,50,620,50,625,50,632,50,638,50,643,50,647,50,652,50,656,50,660,50,664,50,668,50],{"viewBox":605,"width":46,"role":47,"ariaLabel":606,"style":49},"0 0 760 185","Bar chart of the initial hydration long task duration before and after server components and lazy hydration.",[52,608],{"className":609,"x":56,"y":56,"width":46,"height":46,"fill":57},[55],[59,611,612],{},"Initial hydration task on destination pages (mobile profile)",[63,614,606],{},[52,616],{"x":67,"y":67,"width":68,"height":617,"rx":70,"fill":71,"stroke":72,"style":73},"183",[75,619,612],{"x":77,"y":78,"fill":72,"style":79},[81,621],{"x1":622,"y1":84,"x2":622,"y2":623,"stroke":86,"strokeWidth":87,"strokeDashArray":624,"style":90},"342.6","163.0",[89,89],[75,626,631],{"x":627,"y":628,"fill":72,"style":629,"textAnchor":630},"237.7","92.0","font-size:13px","end","Eager hydration",[52,633],{"x":634,"y":103,"width":635,"height":636,"rx":106,"fill":71,"stroke":72,"style":637},"249.7","418.3","19","fill-opacity:0.7;stroke-opacity:0.35",[75,639,642],{"x":640,"y":628,"fill":72,"style":641},"674.0","font-size:12px;font-weight:600","900ms",[75,644,646],{"x":627,"y":645,"fill":72,"style":629,"textAnchor":630},"123.0","+ server components for static parts",[52,648],{"x":634,"y":649,"width":650,"height":636,"rx":106,"fill":123,"stroke":86,"style":651},"109.0","223.1","fill-opacity:0.7;stroke-opacity:0.9",[75,653,655],{"x":654,"y":645,"fill":72,"style":641},"478.8","480ms",[75,657,659],{"x":627,"y":658,"fill":72,"style":629,"textAnchor":630},"154.0","+ lazy hydration triggers",[52,661],{"x":634,"y":662,"width":663,"height":636,"rx":106,"fill":123,"stroke":86,"style":651},"140.0","102.3",[75,665,667],{"x":666,"y":658,"fill":72,"style":641},"357.9","220ms",[75,669,670],{"x":622,"y":185,"fill":186,"style":187,"textAnchor":113},"target",[193,672,674],{"id":673},"rolling-out-lazy-hydration-safely","Rolling Out Lazy Hydration Safely",[14,676,677,678,680],{},"Start with components that are clearly below the fold on every viewport and have no early interactions: reviews, related content, footers. Apply ",[270,679,496],{}," or convert them to server components, then test scrolling and interacting on a throttled device. Next, look at widgets that users rarely touch (newsletter forms, share menus) and use interaction triggers. Leave above-the-fold controls eager. After each step, compare the hydration trace and check for regressions such as buttons that appear but do not respond, or content that changes when it hydrates (a sign of hydration mismatches).",[193,682,684],{"id":683},"common-mistakes","Common Mistakes",[198,686,687,693,699,705],{},[201,688,689,692],{},[32,690,691],{},"Lazy-hydrating above-the-fold controls."," Users click and nothing happens.",[201,694,695,698],{},[32,696,697],{},"Static imports of lazy components."," Code stays in the main bundle.",[201,700,701,704],{},[32,702,703],{},"hydrate-never on interactive components."," They never work.",[201,706,707,710],{},[32,708,709],{},"No placeholders for client-only components."," Layout shifts.",[193,712,714],{"id":713},"edge-cases","Edge Cases",[14,716,717,720],{},[32,718,719],{},"Nuxt version."," Built-in hydration triggers are available in recent Nuxt versions; older versions need community modules.",[14,722,723,726],{},[32,724,725],{},"Third-party components."," Wrap them in lazy components to defer both code and hydration.",[14,728,729,732],{},[32,730,731],{},"State shared across lazy components."," State initialised during SSR is in the payload; lazy components read it when they hydrate.",[14,734,735,738],{},[32,736,737],{},"Accessibility."," Ensure non-hydrated content is accessible as static HTML (links work, content readable).",[193,740,742],{"id":741},"faq","FAQ",[744,745,748,752],"details",{"className":746},[747],"faq-item",[749,750,751],"summary",{},"What is lazy hydration?",[14,753,754],{},"Delaying the hydration of a server-rendered component until a trigger, such as visibility, idle time or interaction, instead of hydrating it immediately on load.",[744,756,758,761],{"className":757},[747],[749,759,760],{},"Does lazy hydration hurt SEO?",[14,762,763],{},"No. The HTML is still server-rendered; only the JavaScript activation is delayed.",[744,765,767,770],{"className":766},[747],[749,768,769],{},"What happens if a user clicks before hydration?",[14,771,772],{},"With visibility or idle triggers, the click may do nothing until hydration completes. Use interaction triggers for components users may click early.",[744,774,776,779],{"className":775},[747],[749,777,778],{},"What are Nuxt server components?",[14,780,781,782,784],{},"Components (",[270,783,418],{},") rendered only on the server, sending HTML without client JavaScript. They cannot have client interactivity.",[744,786,788,791],{"className":787},[747],[749,789,790],{},"Is lazy hydration the same as lazy loading components?",[14,792,793],{},"Related but different. Lazy loading defers the component's code; lazy hydration also defers running it on server-rendered HTML.",[744,795,797,800],{"className":796},[747],[749,798,799],{},"Does lazy hydration improve LCP?",[14,801,802],{},"Usually little, since LCP depends on server HTML and resources. It mainly improves TBT and INP.",[744,804,806,809],{"className":805},[747],[749,807,808],{},"Can I lazy-hydrate based on screen size?",[14,810,811],{},"Yes, with a media query trigger, for example hydrating a desktop-only sidebar only on large screens.",[744,813,815,818],{"className":814},[747],[749,816,817],{},"How do I know which components to make lazy?",[14,819,820],{},"Start with components below the fold and heavy widgets; check the hydration trace and bundle analysis for the largest contributors.",[744,822,824,827],{"className":823},[747],[749,825,826],{},"Does lazy hydration change the HTML?",[14,828,829],{},"No. Components are still server-rendered; only the client-side activation is deferred.",[744,831,833,836],{"className":832},[747],[749,834,835],{},"Can lazy hydration cause hydration mismatches?",[14,837,838],{},"Not by itself. Mismatches come from differences between server and client rendering, such as dates or random values; fix those regardless of hydration timing.",[193,840,842],{"id":841},"related","Related",[198,844,845,852,859],{},[201,846,847,851],{},[18,848,850],{"href":849},"\u002Fframework-performance\u002Fvue-and-nuxt-performance\u002Freducing-nuxt-payload-size\u002F","Reducing Nuxt payload size"," — less state to revive.",[201,853,854,858],{},[18,855,857],{"href":856},"\u002Fframework-performance\u002Fastro-and-sveltekit-performance\u002Fchoosing-astro-client-directives\u002F","Choosing Astro client directives"," — the islands version of the same idea.",[201,860,861,865],{},[18,862,864],{"href":863},"\u002Fframework-performance\u002Fangular-performance\u002Fdeferring-components-with-angular-defer-blocks\u002F","Deferring components with Angular @defer blocks"," — Angular's equivalent.",[867,868,870],"script",{"type":869},"application\u002Fld+json","\n{\n  \"@context\": \"https:\u002F\u002Fschema.org\",\n  \"@type\": \"HowTo\",\n  \"name\": \"Lazy Hydration in Nuxt\",\n  \"description\": \"How to use Nuxt's lazy hydration triggers and server components so pages hydrate only what users need, when they need it.\",\n  \"step\": [\n    {\n      \"@type\": \"HowToStep\",\n      \"position\": 1,\n      \"name\": \"Use hydration triggers on lazy components\",\n      \"text\": \"Prefixing a component with Lazy splits its code into a separate chunk; the hydrate-* props control when it hydrates.\"\n    },\n    {\n      \"@type\": \"HowToStep\",\n      \"position\": 2,\n      \"name\": \"Make static sections server components\",\n      \"text\": \"Rename static components to .server.vue (with server components enabled) so they render only on the server and ship no client code.\"\n    },\n    {\n      \"@type\": \"HowToStep\",\n      \"position\": 3,\n      \"name\": \"Choose triggers by component role\",\n      \"text\": \"Visible for below-the-fold sections, interaction for forms and widgets used occasionally, idle for content that should become interactive soon without competing with load, never for static content.\"\n    },\n    {\n      \"@type\": \"HowToStep\",\n      \"position\": 4,\n      \"name\": \"Reserve space\",\n      \"text\": \"Lazy-hydrated components are server-rendered, so their layout is present; client-only components () need sized placeholders to avoid CLS.\"\n    }\n  ]\n}\n",[867,872,873],{"type":869},"\n{\n  \"@context\": \"https:\u002F\u002Fschema.org\",\n  \"@type\": \"TechArticle\",\n  \"headline\": \"Lazy Hydration in Nuxt\",\n  \"description\": \"How to use Nuxt's lazy hydration triggers and server components so pages hydrate only what users need, when they need it.\",\n  \"datePublished\": \"2026-10-06\",\n  \"dateModified\": \"2026-10-06\",\n  \"author\": {\n    \"@type\": \"Organization\",\n    \"name\": \"frontend-performance.com\"\n  },\n  \"publisher\": {\n    \"@type\": \"Organization\",\n    \"name\": \"frontend-performance.com\"\n  },\n  \"mainEntityOfPage\": {\n    \"@type\": \"WebPage\",\n    \"@id\": \"https:\u002F\u002Ffrontend-performance.com\u002Fframework-performance\u002Fvue-and-nuxt-performance\u002Flazy-hydration-in-nuxt\u002F\"\n  }\n}\n",[867,875,876],{"type":869},"\n{\n  \"@context\": \"https:\u002F\u002Fschema.org\",\n  \"@type\": \"BreadcrumbList\",\n  \"itemListElement\": [\n    {\n      \"@type\": \"ListItem\",\n      \"position\": 1,\n      \"name\": \"Home\",\n      \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002F\"\n    },\n    {\n      \"@type\": \"ListItem\",\n      \"position\": 2,\n      \"name\": \"Framework Performance\",\n      \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002Fframework-performance\u002F\"\n    },\n    {\n      \"@type\": \"ListItem\",\n      \"position\": 3,\n      \"name\": \"Vue & Nuxt Performance\",\n      \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002Fframework-performance\u002Fvue-and-nuxt-performance\u002F\"\n    },\n    {\n      \"@type\": \"ListItem\",\n      \"position\": 4,\n      \"name\": \"Lazy Hydration in Nuxt\",\n      \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002Fframework-performance\u002Fvue-and-nuxt-performance\u002Flazy-hydration-in-nuxt\u002F\"\n    }\n  ]\n}\n",[878,879,880],"style",{},"html pre.shiki code .saISM, html code.shiki .saISM{--shiki-default:#0E1116;--shiki-dark:#F0F3F6;--shiki-light:#0E1116}html pre.shiki code .sZBmE, html code.shiki .sZBmE{--shiki-default:#024C1A;--shiki-dark:#72F088;--shiki-light:#024C1A}html pre.shiki code .si8lv, html code.shiki .si8lv{--shiki-default:#6E011A;--shiki-default-font-style:italic;--shiki-dark:#FFB1AF;--shiki-dark-font-style:italic;--shiki-light:#6E011A;--shiki-light-font-style:italic}html pre.shiki code .sPXB4, html code.shiki .sPXB4{--shiki-default:#023B95;--shiki-dark:#91CBFF;--shiki-light:#023B95}html pre.shiki code .sZ8jY, html code.shiki .sZ8jY{--shiki-default:#032563;--shiki-dark:#ADDCFF;--shiki-light:#032563}html pre.shiki code .sjfSM, html code.shiki .sjfSM{--shiki-default:#66707B;--shiki-dark:#BDC4CC;--shiki-light:#66707B}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 .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}",{"title":268,"searchDepth":289,"depth":289,"links":882},[883,884,885,891,892,893,894,895,896,897,898,899],{"id":195,"depth":289,"text":196},{"id":227,"depth":289,"text":228},{"id":255,"depth":289,"text":256,"children":886},[887,888,889,890],{"id":260,"depth":313,"text":261},{"id":411,"depth":313,"text":412},{"id":422,"depth":313,"text":423},{"id":429,"depth":313,"text":430},{"id":571,"depth":289,"text":572},{"id":578,"depth":289,"text":579},{"id":585,"depth":289,"text":586},{"id":596,"depth":289,"text":597},{"id":673,"depth":289,"text":674},{"id":683,"depth":289,"text":684},{"id":713,"depth":289,"text":714},{"id":741,"depth":289,"text":742},{"id":841,"depth":289,"text":842},"How to use Nuxt's lazy hydration triggers and server components so pages hydrate only what users need, when they need it.","md",{"slug":12,"type":903,"breadcrumb":904,"datePublished":912,"dateModified":912},"article",[905,908,909,910],{"name":906,"url":907},"Home","\u002F",{"name":26,"url":25},{"name":21,"url":20},{"name":5,"url":911},"\u002Fframework-performance\u002Fvue-and-nuxt-performance\u002Flazy-hydration-in-nuxt\u002F","2026-10-06",true,"\u002Fframework-performance\u002Fvue-and-nuxt-performance\u002Flazy-hydration-in-nuxt",{"title":916,"description":917},"Lazy Hydration in Nuxt: Visible, Idle and Interaction","Delay hydration of below-the-fold Nuxt components with hydrate-on-visible, idle and interaction triggers, and skip it with server components to cut TBT and INP.","framework-performance\u002Fvue-and-nuxt-performance\u002Flazy-hydration-in-nuxt\u002Findex","40fjk7qJREBBZc3NEi8UGFZ23uP4GnVPwUKbsimMu3I",[921,925],{"title":922,"path":923,"stem":924},"Cutting Vue Reactivity Cost with shallowRef","\u002Fframework-performance\u002Fvue-and-nuxt-performance\u002Fcutting-vue-reactivity-cost-with-shallowref","framework-performance\u002Fvue-and-nuxt-performance\u002Fcutting-vue-reactivity-cost-with-shallowref\u002Findex",{"title":926,"path":927,"stem":928},"Nuxt Route Rules for Hybrid Rendering","\u002Fframework-performance\u002Fvue-and-nuxt-performance\u002Fnuxt-route-rules-for-hybrid-rendering","framework-performance\u002Fvue-and-nuxt-performance\u002Fnuxt-route-rules-for-hybrid-rendering\u002Findex",1791308078157]