[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M69B6478TS22P136B0N54HJX":3,"skill-same:01M69B6478TS22P136B0N54HJX":63},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":23,"publishedAt":29,"linkOnly":30,"markdownContent":31,"markdownBody":32,"frontMatter":33,"refName":34,"commitSha":35,"skillDirectory":36,"forksCount":37,"repositoryHtmlUrl":38,"repositoryHomepageUrl":6,"ownerHtmlUrl":39,"ownerBlogUrl":40,"ownerDescription":41,"updatedAt":42,"install":43,"resources":56},"01M69B6478TS22P136B0N54HJX","system-type-spa",null,"Domain patterns for single-page application architecture — client-side routing, state management, rendering strategies, authentication, performance, and offline support. Use when designing or evaluating a browser-based SPA, progressive web app, or rich client-side application.","microsoft\u002Famplifier-bundle-systems-design","microsoft","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F6154722?v=4","01M698VYDXZ6JW5WH3CRV650R8","Microsoft","01M69B51GBR7WTZ199PCPYGB6S",5,"MIT","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Famplifier-bundle-systems-design\u002Fblob\u002Fmain\u002Fskills\u002Fsystem-type-spa\u002FSKILL.md",[18],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000009","前端开发","SCENARIO","使用场景",[24,25,26,27,28],"system type spa","performance","support","web","architecture","2026-11-10 10:12:30",false,"---\nname: system-type-spa\ndescription: \"Domain patterns for single-page application architecture — client-side routing, state management, rendering strategies, authentication, performance, and offline support. Use when designing or evaluating a browser-based SPA, progressive web app, or rich client-side application.\"\n---\n\n# System Type: Single-Page Application (SPA)\n\nPatterns, failure modes, and anti-patterns for browser-based single-page applications.\n\n---\n\n## Rendering Strategies\n\n### Client-Side Rendering (CSR)\n**When to use.** Interactive applications where SEO is not critical — dashboards, admin panels, internal tools, authenticated experiences. When the team already has frontend expertise and the app's value is in interactivity, not content discovery.\n**When to avoid.** Content-heavy marketing sites, blogs, e-commerce product pages — anything where first meaningful paint and SEO matter. When users are on slow devices or unreliable networks.\n**Key decisions.** Shell loading strategy (skeleton screens vs spinners), code splitting granularity, initial bundle size budget, CDN caching for static assets.\n\n### Server-Side Rendering (SSR)\n**When to use.** When first contentful paint matters for conversion. Public-facing pages that need SEO. When you need the interactivity of a SPA but can't sacrifice initial load performance.\n**When to avoid.** Purely authenticated apps where crawlers never see content. When the backend team can't support a Node.js rendering tier. When the added infrastructure complexity isn't justified by the SEO\u002Fperformance benefit.\n**Key decisions.** Hydration strategy (full hydration, partial, progressive, islands), streaming vs buffered SSR, caching rendered HTML, handling authentication during SSR, server cost for rendering.\n\n### Static Site Generation (SSG)\n**When to use.** Content that changes infrequently — documentation, marketing pages, blogs. When you want SPA-like navigation but with pre-built HTML for instant loads.\n**When to avoid.** Highly dynamic, personalized content. Pages that change per-user or per-request. Large sites with millions of pages where build times become prohibitive.\n**Key decisions.** Build frequency, incremental regeneration strategy, preview\u002Fdraft workflow, handling dynamic sections within static pages.\n\n### Islands Architecture\n**When to use.** Mostly-static pages with isolated interactive widgets. When you want to ship minimal JavaScript and hydrate only the components that need interactivity.\n**When to avoid.** Heavily interactive applications where most of the page is dynamic. When shared state between islands creates coupling that negates the isolation benefit.\n**Key decisions.** Island boundary identification, shared state between islands, framework choice (Astro, Fresh, 11ty), progressive enhancement baseline.\n\n## Client-Side Routing\n\n### Hash-Based Routing\n**When to use.** Legacy browser support. Deployments where you can't configure server-side fallback routes (e.g., static file hosting without URL rewriting). Simple applications that don't need clean URLs.\n**When to avoid.** Any modern application where clean URLs matter. When anchor links are needed for in-page navigation.\n**Key decisions.** None significant — this is a fallback strategy, not a primary choice.\n\n### History API Routing\n**When to use.** The default for modern SPAs. Clean URLs, proper browser back\u002Fforward behavior, shareable deep links.\n**When to avoid.** Environments where the server can't be configured to serve the SPA shell for all routes (static hosting without rewrite rules). In those cases, hash routing or SSG is better.\n**Key decisions.** Server fallback configuration (all unmatched routes serve index.html), route-based code splitting, scroll restoration, route transition animations, route guards for authentication.\n\n### Route-Based Code Splitting\n**When to use.** Any SPA beyond trivial size. Load code for a route only when the user navigates to it. Essential for keeping initial bundle size manageable.\n**When to avoid.** Extremely small applications where the overhead of chunking exceeds the benefit.\n**Key decisions.** Chunk granularity (per route, per feature, per library), preloading strategy for likely next routes, loading state during chunk fetch, handling chunk load failures (version mismatch after deployment).\n\n## State Management\n\n### Local Component State\n**When to use.** UI state that belongs to a single component — form inputs, toggles, dropdown open\u002Fclosed, animation state. The default; reach for shared state only when local state creates prop drilling pain.\n**When to avoid.** State that multiple unrelated components need. State that must survive component unmounting.\n**Key decisions.** When to lift state vs. when to share it. Keeping state as close to where it's used as possible.\n\n### Global State (Redux, Zustand, Jotai, Signals)\n**When to use.** State shared across many components — user session, feature flags, shopping cart, notification queue. State that must be inspectable and debuggable (Redux DevTools). State with complex update logic that benefits from centralization.\n**When to avoid.** Simple applications where React context or component state suffices. Using global state as a default rather than an escalation — this is the most common state management mistake.\n**Key decisions.** Store shape (normalized vs nested), selector granularity (over-subscribing causes re-renders), middleware for side effects, persistence strategy, hydration from SSR.\n\n### Server State (React Query, SWR, Apollo)\n**When to use.** Any data that comes from a server and may be stale. These libraries handle caching, revalidation, deduplication, and background refresh — problems you will solve badly if you solve them manually.\n**When to avoid.** Purely local state. Offline-first applications where the server is not the source of truth.\n**Key decisions.** Cache invalidation strategy, stale-while-revalidate timing, optimistic updates, error retry policy, query key design (determines cache boundaries), prefetching strategy.\n\n### URL State\n**When to use.** Filter selections, search queries, pagination, sort order — anything the user should be able to bookmark or share via URL. Often overlooked as a state management tool.\n**When to avoid.** Sensitive data. High-frequency updates (every keystroke). State that doesn't make sense to share or bookmark.\n**Key decisions.** Serialization format (query params vs path segments), default value handling, URL length limits, backward compatibility when URL schema changes.\n\n## Authentication Patterns\n\n### Token-Based (JWT)\n**When to use.** SPAs that call APIs on a different domain. When the backend is stateless. When you need to include claims (roles, permissions) in the token to reduce backend lookups.\n**When to avoid.** When you can use HTTP-only cookies instead (same-domain APIs) — cookies are harder to steal via XSS. When token revocation is a hard requirement (JWTs are valid until expiry).\n**Key decisions.** Storage location (memory vs localStorage — memory is safer, localStorage survives refresh), refresh token rotation, token expiry duration, silent refresh mechanism, logout propagation across tabs.\n\n### HTTP-Only Cookie\n**When to use.** When the API is on the same domain (or a subdomain). The most secure browser storage mechanism — not accessible to JavaScript, eliminating the XSS token theft vector.\n**When to avoid.** Cross-origin API calls where cookies can't be sent. Mobile app backends where cookies are awkward.\n**Key decisions.** SameSite attribute (Strict vs Lax), CSRF protection (double-submit cookie or synchronizer token), cookie scope (domain, path), secure flag enforcement.\n\n### OAuth \u002F OIDC Flows\n**When to use.** Third-party login (Google, GitHub, Microsoft). Enterprise SSO. When you don't want to manage passwords.\n**When to avoid.** Simple applications with only email\u002Fpassword auth where the OAuth complexity isn't justified.\n**Key decisions.** Authorization Code flow with PKCE (required for SPAs — implicit flow is deprecated), redirect vs popup, state parameter for CSRF, token storage after callback, session management across tabs.\n\n## Performance\n\n### Bundle Size\n**What it costs.** Every kilobyte of JavaScript must be downloaded, parsed, and executed. On a mid-range mobile device, 1 MB of JavaScript can take 3-4 seconds to parse alone. Bundle size is the single largest performance lever for SPAs.\n**Key strategies.** Tree shaking (ensure ESM imports), code splitting by route and feature, dynamic imports for heavy libraries, bundle analysis (webpack-bundle-analyzer, source-map-explorer), size budgets enforced in CI, replacing heavy libraries with lighter alternatives.\n\n### Rendering Performance\n**What it costs.** Unnecessary re-renders cause jank, input lag, and battery drain. React's reconciliation is fast but not free — large component trees with frequent updates are the primary source of SPA sluggishness.\n**Key strategies.** Memoization (React.memo, useMemo, useCallback — but measure first), virtualized lists for large datasets, debounced inputs, avoiding state updates that trigger full tree re-renders, profiler-guided optimization (React DevTools Profiler, Chrome Performance tab).\n\n### Network Performance\n**What it costs.** API waterfalls — sequential requests where one fetch depends on another — are the most common cause of slow SPA page loads. Users perceive network-bound delays as the app being slow.\n**Key strategies.** Parallel data fetching, request deduplication, prefetching on hover\u002Ffocus, cache-first patterns for stable data, skeleton screens that match actual layout, avoiding layout shift during load.\n\n### Core Web Vitals\n**What it costs.** LCP (Largest Contentful Paint), INP (Interaction to Next Paint), and CLS (Cumulative Layout Shift) directly affect search ranking and user perception. SPAs historically struggle with all three.\n**Key strategies.** Preload critical resources, inline critical CSS, reserve space for dynamic content (prevents CLS), break long tasks to keep main thread responsive (improves INP), use loading=\"lazy\" for below-fold images.\n\n## Offline and PWA\n\n### Service Workers\n**When to use.** Offline support, background sync, push notifications, asset precaching. Any SPA that should work (even partially) without a network connection.\n**When to avoid.** Applications where stale data is dangerous (financial dashboards, real-time monitoring). When the team doesn't understand service worker lifecycle — a broken service worker can cache bad code with no recovery path for users.\n**Key decisions.** Caching strategy per resource type (cache-first for assets, network-first for API), cache versioning and cleanup, update notification to users (\"new version available\"), scope management, handling service worker update when tabs are open.\n\n### Offline Data\n**When to use.** Applications used in unreliable network conditions — field work, mobile, transit. Forms that should not lose data on disconnection.\n**When to avoid.** When the conflict resolution complexity exceeds the offline benefit. When data freshness is critical and stale data causes harm.\n**Key decisions.** Local storage technology (IndexedDB for structured data, localStorage for simple key-value), sync strategy (background sync API, manual queue), conflict resolution on reconnection, storage quota management, user communication about offline state.\n\n## Common Failure Modes\n\n- **Stale deployment cache.** Users load cached JavaScript bundles that reference API contracts or chunk filenames that no longer exist. Mitigation: content-hashed filenames, versioned API endpoints, chunk load error handling that forces a page refresh.\n- **Memory leaks from event listeners and subscriptions.** Components mount listeners or subscriptions and never clean them up. Over time, the tab consumes gigabytes. Mitigation: cleanup in useEffect return \u002F componentWillUnmount, WeakRef where appropriate, monitoring tab memory in production.\n- **White screen of death.** An unhandled JavaScript error crashes the entire component tree. Mitigation: error boundaries at route and feature level, fallback UI, error reporting to monitoring service.\n- **State desynchronization.** Client state diverges from server state — the user sees stale data, makes decisions on wrong information, or submits conflicting updates. Mitigation: server state as source of truth (React Query\u002FSWR), optimistic update rollback on failure, staleness indicators.\n- **Infinite loading states.** A failed network request with no timeout or error handling leaves the user staring at a spinner forever. Mitigation: request timeouts, error states with retry, circuit breaker for known-failing endpoints.\n- **Route-level code split failures.** After a deployment, users on old cached pages try to navigate to a route whose chunk filename has changed. The dynamic import fails silently. Mitigation: chunk error detection, automatic page reload on chunk load failure, service worker precaching of route chunks.\n- **Authentication token expiry during use.** The user is mid-workflow when their token expires. The next API call fails, and unsaved work is lost. Mitigation: silent token refresh before expiry, queuing requests during refresh, saving form state to localStorage as backup.\n- **Hydration mismatch.** SSR HTML doesn't match what the client renders, causing React to discard the server-rendered DOM and re-render from scratch — negating the SSR performance benefit. Mitigation: ensure server and client render identical output, suppress hydration warnings only as last resort, avoid browser-only APIs during SSR (window, localStorage).\n\n## Anti-Patterns\n\n- **Mega-bundle.** Shipping the entire application as a single JavaScript file. Users download megabytes of code they won't use on the current page. Split by route at minimum.\n- **Global state for everything.** Putting form input state, UI toggles, and animation state into Redux\u002FZustand. Global state is for shared, cross-cutting concerns — not a replacement for component state.\n- **Prop drilling avoidance via global state.** Reaching for a global store because props pass through 3 components. Composition (children, render props, context) solves this without the overhead.\n- **Direct DOM manipulation.** Using querySelector or innerHTML alongside a virtual DOM framework. The framework can't track changes it didn't make, leading to subtle rendering bugs.\n- **Client-side security.** Hiding UI elements instead of enforcing permissions on the API. Every API endpoint must validate authorization independently — the client is untrusted.\n- **Storing secrets in JavaScript.** API keys, service credentials, or admin tokens in client-side code. JavaScript source is fully visible to users. Use a backend proxy for authenticated third-party calls.\n- **SPA for content sites.** Building a blog, documentation site, or marketing page as a CSR SPA. These need SEO, fast first paint, and work without JavaScript. Use SSG or SSR.\n- **Ignoring accessibility.** SPAs break native browser accessibility by default — no page load announcements, focus management on route change, or semantic HTML. Accessibility must be designed in, not retrofitted.\n- **No loading or error states.** Assuming every API call succeeds instantly. Every async operation needs three states: loading, success, error. Skipping any of these guarantees a bad user experience.\n- **Over-abstracting too early.** Creating a generic DataFetcher, FormBuilder, or LayoutEngine before understanding the actual use cases. Premature abstraction in frontend code creates rigid, hard-to-debug component hierarchies.\n","# System Type: Single-Page Application (SPA)\n\nPatterns, failure modes, and anti-patterns for browser-based single-page applications.\n\n---\n\n## Rendering Strategies\n\n### Client-Side Rendering (CSR)\n**When to use.** Interactive applications where SEO is not critical — dashboards, admin panels, internal tools, authenticated experiences. When the team already has frontend expertise and the app's value is in interactivity, not content discovery.\n**When to avoid.** Content-heavy marketing sites, blogs, e-commerce product pages — anything where first meaningful paint and SEO matter. When users are on slow devices or unreliable networks.\n**Key decisions.** Shell loading strategy (skeleton screens vs spinners), code splitting granularity, initial bundle size budget, CDN caching for static assets.\n\n### Server-Side Rendering (SSR)\n**When to use.** When first contentful paint matters for conversion. Public-facing pages that need SEO. When you need the interactivity of a SPA but can't sacrifice initial load performance.\n**When to avoid.** Purely authenticated apps where crawlers never see content. When the backend team can't support a Node.js rendering tier. When the added infrastructure complexity isn't justified by the SEO\u002Fperformance benefit.\n**Key decisions.** Hydration strategy (full hydration, partial, progressive, islands), streaming vs buffered SSR, caching rendered HTML, handling authentication during SSR, server cost for rendering.\n\n### Static Site Generation (SSG)\n**When to use.** Content that changes infrequently — documentation, marketing pages, blogs. When you want SPA-like navigation but with pre-built HTML for instant loads.\n**When to avoid.** Highly dynamic, personalized content. Pages that change per-user or per-request. Large sites with millions of pages where build times become prohibitive.\n**Key decisions.** Build frequency, incremental regeneration strategy, preview\u002Fdraft workflow, handling dynamic sections within static pages.\n\n### Islands Architecture\n**When to use.** Mostly-static pages with isolated interactive widgets. When you want to ship minimal JavaScript and hydrate only the components that need interactivity.\n**When to avoid.** Heavily interactive applications where most of the page is dynamic. When shared state between islands creates coupling that negates the isolation benefit.\n**Key decisions.** Island boundary identification, shared state between islands, framework choice (Astro, Fresh, 11ty), progressive enhancement baseline.\n\n## Client-Side Routing\n\n### Hash-Based Routing\n**When to use.** Legacy browser support. Deployments where you can't configure server-side fallback routes (e.g., static file hosting without URL rewriting). Simple applications that don't need clean URLs.\n**When to avoid.** Any modern application where clean URLs matter. When anchor links are needed for in-page navigation.\n**Key decisions.** None significant — this is a fallback strategy, not a primary choice.\n\n### History API Routing\n**When to use.** The default for modern SPAs. Clean URLs, proper browser back\u002Fforward behavior, shareable deep links.\n**When to avoid.** Environments where the server can't be configured to serve the SPA shell for all routes (static hosting without rewrite rules). In those cases, hash routing or SSG is better.\n**Key decisions.** Server fallback configuration (all unmatched routes serve index.html), route-based code splitting, scroll restoration, route transition animations, route guards for authentication.\n\n### Route-Based Code Splitting\n**When to use.** Any SPA beyond trivial size. Load code for a route only when the user navigates to it. Essential for keeping initial bundle size manageable.\n**When to avoid.** Extremely small applications where the overhead of chunking exceeds the benefit.\n**Key decisions.** Chunk granularity (per route, per feature, per library), preloading strategy for likely next routes, loading state during chunk fetch, handling chunk load failures (version mismatch after deployment).\n\n## State Management\n\n### Local Component State\n**When to use.** UI state that belongs to a single component — form inputs, toggles, dropdown open\u002Fclosed, animation state. The default; reach for shared state only when local state creates prop drilling pain.\n**When to avoid.** State that multiple unrelated components need. State that must survive component unmounting.\n**Key decisions.** When to lift state vs. when to share it. Keeping state as close to where it's used as possible.\n\n### Global State (Redux, Zustand, Jotai, Signals)\n**When to use.** State shared across many components — user session, feature flags, shopping cart, notification queue. State that must be inspectable and debuggable (Redux DevTools). State with complex update logic that benefits from centralization.\n**When to avoid.** Simple applications where React context or component state suffices. Using global state as a default rather than an escalation — this is the most common state management mistake.\n**Key decisions.** Store shape (normalized vs nested), selector granularity (over-subscribing causes re-renders), middleware for side effects, persistence strategy, hydration from SSR.\n\n### Server State (React Query, SWR, Apollo)\n**When to use.** Any data that comes from a server and may be stale. These libraries handle caching, revalidation, deduplication, and background refresh — problems you will solve badly if you solve them manually.\n**When to avoid.** Purely local state. Offline-first applications where the server is not the source of truth.\n**Key decisions.** Cache invalidation strategy, stale-while-revalidate timing, optimistic updates, error retry policy, query key design (determines cache boundaries), prefetching strategy.\n\n### URL State\n**When to use.** Filter selections, search queries, pagination, sort order — anything the user should be able to bookmark or share via URL. Often overlooked as a state management tool.\n**When to avoid.** Sensitive data. High-frequency updates (every keystroke). State that doesn't make sense to share or bookmark.\n**Key decisions.** Serialization format (query params vs path segments), default value handling, URL length limits, backward compatibility when URL schema changes.\n\n## Authentication Patterns\n\n### Token-Based (JWT)\n**When to use.** SPAs that call APIs on a different domain. When the backend is stateless. When you need to include claims (roles, permissions) in the token to reduce backend lookups.\n**When to avoid.** When you can use HTTP-only cookies instead (same-domain APIs) — cookies are harder to steal via XSS. When token revocation is a hard requirement (JWTs are valid until expiry).\n**Key decisions.** Storage location (memory vs localStorage — memory is safer, localStorage survives refresh), refresh token rotation, token expiry duration, silent refresh mechanism, logout propagation across tabs.\n\n### HTTP-Only Cookie\n**When to use.** When the API is on the same domain (or a subdomain). The most secure browser storage mechanism — not accessible to JavaScript, eliminating the XSS token theft vector.\n**When to avoid.** Cross-origin API calls where cookies can't be sent. Mobile app backends where cookies are awkward.\n**Key decisions.** SameSite attribute (Strict vs Lax), CSRF protection (double-submit cookie or synchronizer token), cookie scope (domain, path), secure flag enforcement.\n\n### OAuth \u002F OIDC Flows\n**When to use.** Third-party login (Google, GitHub, Microsoft). Enterprise SSO. When you don't want to manage passwords.\n**When to avoid.** Simple applications with only email\u002Fpassword auth where the OAuth complexity isn't justified.\n**Key decisions.** Authorization Code flow with PKCE (required for SPAs — implicit flow is deprecated), redirect vs popup, state parameter for CSRF, token storage after callback, session management across tabs.\n\n## Performance\n\n### Bundle Size\n**What it costs.** Every kilobyte of JavaScript must be downloaded, parsed, and executed. On a mid-range mobile device, 1 MB of JavaScript can take 3-4 seconds to parse alone. Bundle size is the single largest performance lever for SPAs.\n**Key strategies.** Tree shaking (ensure ESM imports), code splitting by route and feature, dynamic imports for heavy libraries, bundle analysis (webpack-bundle-analyzer, source-map-explorer), size budgets enforced in CI, replacing heavy libraries with lighter alternatives.\n\n### Rendering Performance\n**What it costs.** Unnecessary re-renders cause jank, input lag, and battery drain. React's reconciliation is fast but not free — large component trees with frequent updates are the primary source of SPA sluggishness.\n**Key strategies.** Memoization (React.memo, useMemo, useCallback — but measure first), virtualized lists for large datasets, debounced inputs, avoiding state updates that trigger full tree re-renders, profiler-guided optimization (React DevTools Profiler, Chrome Performance tab).\n\n### Network Performance\n**What it costs.** API waterfalls — sequential requests where one fetch depends on another — are the most common cause of slow SPA page loads. Users perceive network-bound delays as the app being slow.\n**Key strategies.** Parallel data fetching, request deduplication, prefetching on hover\u002Ffocus, cache-first patterns for stable data, skeleton screens that match actual layout, avoiding layout shift during load.\n\n### Core Web Vitals\n**What it costs.** LCP (Largest Contentful Paint), INP (Interaction to Next Paint), and CLS (Cumulative Layout Shift) directly affect search ranking and user perception. SPAs historically struggle with all three.\n**Key strategies.** Preload critical resources, inline critical CSS, reserve space for dynamic content (prevents CLS), break long tasks to keep main thread responsive (improves INP), use loading=\"lazy\" for below-fold images.\n\n## Offline and PWA\n\n### Service Workers\n**When to use.** Offline support, background sync, push notifications, asset precaching. Any SPA that should work (even partially) without a network connection.\n**When to avoid.** Applications where stale data is dangerous (financial dashboards, real-time monitoring). When the team doesn't understand service worker lifecycle — a broken service worker can cache bad code with no recovery path for users.\n**Key decisions.** Caching strategy per resource type (cache-first for assets, network-first for API), cache versioning and cleanup, update notification to users (\"new version available\"), scope management, handling service worker update when tabs are open.\n\n### Offline Data\n**When to use.** Applications used in unreliable network conditions — field work, mobile, transit. Forms that should not lose data on disconnection.\n**When to avoid.** When the conflict resolution complexity exceeds the offline benefit. When data freshness is critical and stale data causes harm.\n**Key decisions.** Local storage technology (IndexedDB for structured data, localStorage for simple key-value), sync strategy (background sync API, manual queue), conflict resolution on reconnection, storage quota management, user communication about offline state.\n\n## Common Failure Modes\n\n- **Stale deployment cache.** Users load cached JavaScript bundles that reference API contracts or chunk filenames that no longer exist. Mitigation: content-hashed filenames, versioned API endpoints, chunk load error handling that forces a page refresh.\n- **Memory leaks from event listeners and subscriptions.** Components mount listeners or subscriptions and never clean them up. Over time, the tab consumes gigabytes. Mitigation: cleanup in useEffect return \u002F componentWillUnmount, WeakRef where appropriate, monitoring tab memory in production.\n- **White screen of death.** An unhandled JavaScript error crashes the entire component tree. Mitigation: error boundaries at route and feature level, fallback UI, error reporting to monitoring service.\n- **State desynchronization.** Client state diverges from server state — the user sees stale data, makes decisions on wrong information, or submits conflicting updates. Mitigation: server state as source of truth (React Query\u002FSWR), optimistic update rollback on failure, staleness indicators.\n- **Infinite loading states.** A failed network request with no timeout or error handling leaves the user staring at a spinner forever. Mitigation: request timeouts, error states with retry, circuit breaker for known-failing endpoints.\n- **Route-level code split failures.** After a deployment, users on old cached pages try to navigate to a route whose chunk filename has changed. The dynamic import fails silently. Mitigation: chunk error detection, automatic page reload on chunk load failure, service worker precaching of route chunks.\n- **Authentication token expiry during use.** The user is mid-workflow when their token expires. The next API call fails, and unsaved work is lost. Mitigation: silent token refresh before expiry, queuing requests during refresh, saving form state to localStorage as backup.\n- **Hydration mismatch.** SSR HTML doesn't match what the client renders, causing React to discard the server-rendered DOM and re-render from scratch — negating the SSR performance benefit. Mitigation: ensure server and client render identical output, suppress hydration warnings only as last resort, avoid browser-only APIs during SSR (window, localStorage).\n\n## Anti-Patterns\n\n- **Mega-bundle.** Shipping the entire application as a single JavaScript file. Users download megabytes of code they won't use on the current page. Split by route at minimum.\n- **Global state for everything.** Putting form input state, UI toggles, and animation state into Redux\u002FZustand. Global state is for shared, cross-cutting concerns — not a replacement for component state.\n- **Prop drilling avoidance via global state.** Reaching for a global store because props pass through 3 components. Composition (children, render props, context) solves this without the overhead.\n- **Direct DOM manipulation.** Using querySelector or innerHTML alongside a virtual DOM framework. The framework can't track changes it didn't make, leading to subtle rendering bugs.\n- **Client-side security.** Hiding UI elements instead of enforcing permissions on the API. Every API endpoint must validate authorization independently — the client is untrusted.\n- **Storing secrets in JavaScript.** API keys, service credentials, or admin tokens in client-side code. JavaScript source is fully visible to users. Use a backend proxy for authenticated third-party calls.\n- **SPA for content sites.** Building a blog, documentation site, or marketing page as a CSR SPA. These need SEO, fast first paint, and work without JavaScript. Use SSG or SSR.\n- **Ignoring accessibility.** SPAs break native browser accessibility by default — no page load announcements, focus management on route change, or semantic HTML. Accessibility must be designed in, not retrofitted.\n- **No loading or error states.** Assuming every API call succeeds instantly. Every async operation needs three states: loading, success, error. Skipping any of these guarantees a bad user experience.\n- **Over-abstracting too early.** Creating a generic DataFetcher, FormBuilder, or LayoutEngine before understanding the actual use cases. Premature abstraction in frontend code creates rigid, hard-to-debug component hierarchies.\n",{"name":5,"description":7},"main","1eff6a2bcebe7c42d5d8d4962e1937a3bb932b0c","skills\u002Fsystem-type-spa",2,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Famplifier-bundle-systems-design","https:\u002F\u002Fgithub.com\u002Fmicrosoft","https:\u002F\u002Fopensource.microsoft.com","Open source projects and samples from Microsoft","2026-05-18 08:17:41",{"source":8,"skillName":5,"commands":44,"prompt":54,"zipAvailable":55},[45,48,51],{"tool":46,"command":47},"npx","npx skills add microsoft\u002Famplifier-bundle-systems-design --skill system-type-spa",{"tool":49,"command":50},"bunx","bunx skills add microsoft\u002Famplifier-bundle-systems-design --skill system-type-spa",{"tool":52,"command":53},"pnpm","pnpm dlx skills add microsoft\u002Famplifier-bundle-systems-design --skill system-type-spa","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Famplifier-bundle-systems-design\u002Fblob\u002Fmain\u002Fskills\u002Fsystem-type-spa\u002FSKILL.md",true,[57],{"path":58,"resourceType":59,"resourceTypeDesc":60,"sizeBytes":61,"sourceHtmlUrl":62},"LICENSE.txt","LICENSE","许可证",11357,"https:\u002F\u002Fgithub.com\u002Fshengdabai\u002FTony-Claude-Code-Skills\u002Fblob\u002Fmain\u002Fskills\u002F_collections\u002Ftravisvn-awesome-claude-skills\u002Fanthropics-skills\u002Fskills\u002Fbrand-guidelines\u002FLICENSE.txt",[64,73,91,102,115,124],{"skillNo":65,"name":66,"nameZh":6,"description":67,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":68,"categories":69,"keywords":70,"publishedAt":29},"01M69B6EYN524WJM12A67ASYHS","tradeoff-analysis","Structured tradeoff analysis methodology — the 8-dimension comparison frame, tradeoff matrix template, and common tradeoff patterns. Use when evaluating design alternatives, comparing technology choices, or when the answer is 'it depends.'","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Famplifier-bundle-systems-design\u002Fblob\u002Fmain\u002Fskills\u002Ftradeoff-analysis\u002FSKILL.md",[],[71,72],"tradeoff analysis","design",{"skillNo":74,"name":75,"nameZh":6,"description":76,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":77,"categories":78,"keywords":87,"publishedAt":29},"01M69B6DE6YFEZS2D8RWSFPAVC","systems-design-review-methodology","Use when the \u002Fsystems-design-review mode is active. 7-step design review methodology -- understand the design, classify the system, evaluate against codebase, adversarial analysis, tradeoff validation, synthesis, and action items. Governs conversation flow, delegation patterns, and user validation checkpoints.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Famplifier-bundle-systems-design\u002Fblob\u002Fmain\u002Fskills\u002Fsystems-design-review-methodology\u002FSKILL.md",[79,82],{"categoryNo":80,"categoryName":81,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000015","视觉设计",{"categoryNo":83,"categoryName":84,"taxonomyType":85,"taxonomyTypeDesc":86},"01JBSEEDCAT000000000000032","设计师","PROFESSION","适用职业",[88,89,90,72],"systems design review methodology","design review","review",{"skillNo":92,"name":93,"nameZh":6,"description":94,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":95,"categories":96,"keywords":99,"publishedAt":29},"01M69B6BG8XVGB2QMNFKFYBZVX","systems-design-methodology","Use when the \u002Fsystems-design mode is active. 9-phase structured design methodology -- problem framing, system classification, constraints, candidate architectures, tradeoff analysis, risk review, refinement, migration planning, and documentation. Governs conversation flow, delegation patterns, and user validation checkpoints.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Famplifier-bundle-systems-design\u002Fblob\u002Fmain\u002Fskills\u002Fsystems-design-methodology\u002FSKILL.md",[97,98],{"categoryNo":80,"categoryName":81,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":83,"categoryName":84,"taxonomyType":85,"taxonomyTypeDesc":86},[72,100,90,101],"systems design methodology","documentation",{"skillNo":103,"name":104,"nameZh":6,"description":105,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":106,"categories":107,"keywords":111,"publishedAt":29},"01M69B69R21TMX6E7WVH241YW7","system-type-workflow-orchestration","Domain patterns for workflow orchestration systems — long-running processes, state machines, saga coordination, human-in-the-loop gates, retry and timeout hierarchies, and failure modes. Use when designing or evaluating workflow engines, job orchestrators, or multi-step business process systems.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Famplifier-bundle-systems-design\u002Fblob\u002Fmain\u002Fskills\u002Fsystem-type-workflow-orchestration\u002FSKILL.md",[108],{"categoryNo":109,"categoryName":110,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",[112,113,114],"system type workflow orchestration","workflow","orchestration",{"skillNo":116,"name":117,"nameZh":6,"description":118,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":119,"categories":120,"keywords":121,"publishedAt":29},"01M69B67T9XSXZFZMS8BA8XTN4","system-type-web-service","Domain patterns for web service architecture — API design (REST\u002FGraphQL\u002FgRPC), scaling, data layer, observability, failure modes, and anti-patterns. Use when designing or evaluating a web service, API, or request\u002Fresponse system.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Famplifier-bundle-systems-design\u002Fblob\u002Fmain\u002Fskills\u002Fsystem-type-web-service\u002FSKILL.md",[],[122,27,123,28,72],"system type web service","api design",{"skillNo":125,"name":126,"nameZh":6,"description":127,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":128,"categories":129,"keywords":130,"publishedAt":29},"01M69B62JJKQ2XRD5ZW0RW33KT","system-type-real-time","Domain patterns for real-time and collaborative systems — persistent connections, state synchronization, conflict resolution, presence, fan-out, and failure modes. Use when designing or evaluating chat systems, collaborative editors, live dashboards, gaming backends, or any system with bidirectional real-time communication.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Famplifier-bundle-systems-design\u002Fblob\u002Fmain\u002Fskills\u002Fsystem-type-real-time\u002FSKILL.md",[],[131,132],"real time","system type real time"]