feat: Complete fleet — 94 skills across 10+ domains
Pulled ALL skills from 15 source repositories: - anthropics/skills: 16 (docs, design, MCP, testing) - obra/superpowers: 14 (TDD, debugging, agents, planning) - coreyhaines31/marketingskills: 25 (marketing, CRO, SEO, growth) - better-auth/skills: 5 (auth patterns) - vercel-labs/agent-skills: 5 (React, design, Vercel) - antfu/skills: 16 (Vue, Vite, Vitest, pnpm, Turborepo) - Plus 13 individual skills from various repos Mosaic Stack is not limited to coding — the Orchestrator and subagents serve coding, business, design, marketing, writing, logistics, analysis, and more. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,170 @@
|
||||
---
|
||||
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
|
||||
// <div id="app"></div>
|
||||
```
|
||||
|
||||
**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
|
||||
<!-- pages/index.vue - Works with both SSR and SSG -->
|
||||
<template>
|
||||
<div>
|
||||
<HeroSection />
|
||||
<FeatureList :features="features" />
|
||||
<PricingTable />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
// Data fetched at build time (SSG) or request time (SSR)
|
||||
const { data: features } = await useFetch('/api/features')
|
||||
</script>
|
||||
```
|
||||
|
||||
## 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(`
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head><title>My App</title></head>
|
||||
<body>
|
||||
<div id="app">${html}</div>
|
||||
<script type="module" src="/client.js"></script>
|
||||
</body>
|
||||
</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/)
|
||||
Reference in New Issue
Block a user