--- title: Use SSR or SSG for Page Load Critical Applications impact: HIGH impactDescription: Client-side SPAs require JavaScript execution before content appears, severely impacting LCP and INP metrics type: capability tags: [vue3, performance, ssr, ssg, nuxt, page-load, architecture] --- # Use SSR or SSG for Page Load Critical Applications **Impact: HIGH** - Pure client-side SPAs must download, parse, and execute JavaScript before users see content. This significantly delays Largest Contentful Paint (LCP) and impacts Core Web Vitals. For page load-critical apps (marketing sites, e-commerce, content sites), use Server-Side Rendering (SSR) or Static Site Generation (SSG). Choose your architecture based on your content's nature and page load requirements. ## Task Checklist - [ ] Evaluate if page load performance is critical for your use case - [ ] Choose SSR for dynamic content that changes per request - [ ] Choose SSG for content that doesn't change frequently - [ ] Consider hybrid approaches (SSG for marketing, SPA for app) - [ ] Use Nuxt.js for streamlined SSR/SSG with Vue ## Architecture Decision Guide | Content Type | Changes | Best Approach | Example | |--------------|---------|---------------|---------| | Marketing pages | Rarely | SSG | Landing pages, docs | | Blog/content | On publish | SSG with regeneration | Blog, documentation | | E-commerce catalog | Hourly/daily | SSG + ISR | Product listings | | User dashboard | Per request | SPA (ok) | Admin panels | | Social feed | Real-time | SSR or SPA | News feed | | Authenticated app | Per user | SPA (ok) | Internal tools | **Incorrect:** ```javascript // BAD: Pure client-side SPA for a marketing site // Users see blank page until JS loads and executes // main.js import { createApp } from 'vue' import App from './App.vue' createApp(App).mount('#app') // Nothing visible until this runs // index.html - Users see empty #app until JS executes //
``` **Correct:** ```javascript // GOOD: Use Nuxt.js for SSR/SSG // nuxt.config.ts export default defineNuxtConfig({ // SSG: Pre-render at build time (best for static content) ssr: true, nitro: { prerender: { routes: ['/', '/about', '/pricing', '/blog'] } } }) // Or full SSR for dynamic content export default defineNuxtConfig({ ssr: true // Server renders on each request }) ``` ```vue ``` ## Hybrid Approach: SSG Marketing + SPA App ```javascript // nuxt.config.ts - Hybrid rendering export default defineNuxtConfig({ routeRules: { // Static pages - pre-rendered at build '/': { prerender: true }, '/about': { prerender: true }, '/pricing': { prerender: true }, '/blog/**': { prerender: true }, // Dynamic app sections - client-side only '/dashboard/**': { ssr: false }, '/app/**': { ssr: false }, // API routes - server-side '/api/**': { cors: true } } }) ``` ## Manual SSR with Vue (without Nuxt) ```javascript // server.js - Express with Vue SSR import express from 'express' import { createSSRApp } from 'vue' import { renderToString } from 'vue/server-renderer' import App from './App.vue' const app = express() app.get('*', async (req, res) => { const vueApp = createSSRApp(App) const html = await renderToString(vueApp) res.send(` My App
${html}
`) }) ``` ## Performance Impact | Approach | Time to First Byte | LCP | JavaScript Required | |----------|-------------------|-----|---------------------| | Client SPA | Fast | Slow (waits for JS) | Yes, before content | | SSR | Slower | Fast (HTML ready) | No, for initial view | | SSG | Fast (CDN) | Fast (HTML ready) | No, for initial view | ## When Client-Side SPA Is Acceptable - Internal tools and dashboards (users expect loading) - Authenticated applications (initial load happens once) - Real-time collaborative apps (WebSocket-heavy) - PWAs where offline-first is the priority - Complex interactive applications (Figma-like) ## Static Site Generation with Vite ```javascript // vite.config.js - Using vite-ssg for SSG import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' export default defineConfig({ plugins: [vue()], ssgOptions: { script: 'async', formatting: 'minify' } }) ``` ## Reference - [Vue.js Performance - Page Load Optimizations](https://vuejs.org/guide/best-practices/performance.html#page-load-optimizations) - [Vue.js SSR Guide](https://vuejs.org/guide/scaling-up/ssr.html) - [Nuxt.js Documentation](https://nuxt.com/)