{
 "study": "What seven JavaScript frameworks and a client-rendered React app send to crawlers, and how fast the same page loads in each",
 "post": "https://www.seotal.com/blog/best-javascript-frameworks-for-seo",
 "publisher": "Seotal",
 "license": "CC BY 4.0 for the lab measurements. Field columns are HTTP Archive Core Web Vitals Technology Report data (Chrome UX Report); credit HTTP Archive when reusing them.",
 "testPage": {
  "words": 410,
  "paragraphs": 10,
  "elements": [
   "title",
   "meta description",
   "canonical link",
   "og:title",
   "Article JSON-LD",
   "h1",
   "one 1200x630 JPEG with width, height and alt",
   "one client-side Helpful? counter button",
   "two plain anchor links"
  ],
  "note": "Identical content in every framework, rendered with each framework's own idiomatic API for head tags and a client-side component or script for the button. The last paragraph carries a marker string used to confirm the full text is in the HTML."
 },
 "build": "Each framework built the page to static HTML with its own tooling (no hand edits to output). The React SPA HTML shell was copied to the route path to simulate a SPA fallback.",
 "serving": "One local Node static server, gzip level 6 for text assets, no CDN, no caching headers, same machine for every run.",
 "rawHtmlCheck": "One HTTP GET without executing JavaScript (what non-rendering crawlers such as GPTBot, ClaudeBot and PerplexityBot receive); regex checks for each element and for the first and last paragraph text.",
 "lighthouse": {
  "version": "12.8.2",
  "browser": "Brave (Chromium) headless, separate profile",
  "formFactor": "mobile",
  "throttling": "Lighthouse default simulated (150 ms RTT, 1.6 Mbps, 4x CPU)",
  "categories": [
   "performance",
   "seo"
  ],
  "runsPerFramework": 3,
  "aggregation": "median of each metric across the 3 runs, taken independently per metric; per-run values were not kept"
 },
 "jsTotalKb": "Lighthouse resource-summary script transferSize (external scripts, gzip) plus bytes of inline non-JSON-LD script in the HTML.",
 "runWindowUtc": [
  "2026-10-10T17:11:53.715Z",
  "2026-10-10T17:25:18.634Z"
 ],
 "fieldData": {
  "source": "HTTP Archive Core Web Vitals Technology Report",
  "api": "https://cdn.httparchive.org/v1/cwv?technology=<Technology>&geo=ALL&rank=ALL",
  "metric": "overall Core Web Vitals pass: good_number / tested origins",
  "months": [
   "2025-08",
   "2026-08"
  ],
  "retrieved": "2026-10-10"
 },
 "results": {
  "astro": {
   "allRawChecksPassed": true,
   "jsTotalKb": 0.1,
   "performance": 100,
   "seo": 100,
   "lcpMs": 903,
   "tbtMs": 7
  },
  "qwik": {
   "allRawChecksPassed": true,
   "jsTotalKb": 28.1,
   "performance": 100,
   "seo": 100,
   "lcpMs": 1420,
   "tbtMs": 0
  },
  "sveltekit": {
   "allRawChecksPassed": true,
   "jsTotalKb": 37.1,
   "performance": 100,
   "seo": 100,
   "lcpMs": 1614,
   "tbtMs": 40
  },
  "nuxt": {
   "allRawChecksPassed": true,
   "jsTotalKb": 69.8,
   "performance": 100,
   "seo": 100,
   "lcpMs": 1543,
   "tbtMs": 48
  },
  "next": {
   "allRawChecksPassed": true,
   "jsTotalKb": 142.8,
   "performance": 91,
   "seo": 100,
   "lcpMs": 1368,
   "tbtMs": 386
  },
  "reactrouter": {
   "allRawChecksPassed": true,
   "jsTotalKb": 113.8,
   "performance": 99,
   "seo": 100,
   "lcpMs": 1729,
   "tbtMs": 10
  },
  "angular": {
   "allRawChecksPassed": true,
   "jsTotalKb": 76.9,
   "performance": 97,
   "seo": 100,
   "lcpMs": 1419,
   "tbtMs": 179
  },
  "spa": {
   "allRawChecksPassed": false,
   "jsTotalKb": 68.2,
   "performance": 100,
   "seo": 100,
   "lcpMs": 1409,
   "tbtMs": 9
  }
 },
 "caveats": [
  "One small text page per framework: results show each framework's baseline cost, not the speed of a real site built with it.",
  "Lab scores from one Windows laptop; absolute timings vary by machine, relative order is the useful signal.",
  "Field pass rates describe whole populations of sites using each technology, which differ in size, content and third-party scripts; they are correlational, not caused by the framework alone.",
  "Qwik field sample is small (1,334 mobile origins).",
  "Qwik 2 was a release candidate (2.0.0-rc.2) on the test date; the stable 1.20.2 was tested."
 ]
}
