{
  "$schema": "https://datapackage.org/profiles/2.0/datapackage.json",
  "name": "nextjs-partial-prefetching-benchmark-2026-09-23",
  "title": "Partial Prefetching in Next.js 16.3, measured",
  "description": "Lab benchmark of Next.js 16.3 prefetch and caching switches (cacheComponents, partialPrefetching, experimental.prefetchInlining) on one fixture app: prefetch requests and bytes before a click, navigation requests and bytes after it, and click-to-paint times, in headless Chrome with and without Lighthouse-mobile throttling.",
  "version": "2026-09-23",
  "created": "2026-09-23T18:29:34.862Z",
  "homepage": "https://www.outofplace.space/blog/nextjs-partial-prefetching-benchmark",
  "keywords": [
    "Next.js",
    "prefetching",
    "Partial Prefetching",
    "Cache Components",
    "RSC",
    "benchmark"
  ],
  "licenses": [
    {
      "name": "CC-BY-4.0",
      "path": "https://creativecommons.org/licenses/by/4.0/",
      "title": "Creative Commons Attribution 4.0"
    }
  ],
  "contributors": [
    {
      "title": "Outofplace Poland sp. z o.o.",
      "roles": [
        "creator"
      ],
      "path": "https://www.outofplace.space"
    }
  ],
  "sources": [
    {
      "title": "Next.js 16.3.6 (MIT), measured on a generated fixture app; code in scripts/research/next-prefetch",
      "path": "https://github.com/vercel/next.js/releases/tag/v16.3.6"
    }
  ],
  "resources": [
    {
      "name": "runs",
      "path": "runs.csv",
      "title": "One row per measured navigation",
      "type": "table",
      "format": "csv",
      "mediatype": "text/csv",
      "encoding": "utf-8",
      "bytes": 969611,
      "hash": "sha256:52eac3e9ded1086bb832038dddb5517621888fe3f43996084b81f20f0f941027",
      "dialect": {
        "header": true,
        "delimiter": ",",
        "lineTerminator": "\r\n",
        "quoteChar": "\"",
        "doubleQuote": true
      },
      "schema": {
        "fields": [
          {
            "name": "run_id",
            "type": "string",
            "description": "Unique id: pass:rep:variant:scenario:viewport:profile:timing."
          },
          {
            "name": "rep",
            "type": "integer",
            "description": "Repetition index; every cell of one repetition clicks the same target."
          },
          {
            "name": "order",
            "type": "integer",
            "description": "Position in the shuffled global run queue."
          },
          {
            "name": "worker",
            "type": "integer",
            "description": "Worker (browser instance) that ran it."
          },
          {
            "name": "started_at",
            "type": "datetime",
            "description": "UTC start time of the run."
          },
          {
            "name": "load1",
            "type": "number",
            "description": "Host 1-minute load average at run start."
          },
          {
            "name": "protocol",
            "type": "string",
            "description": "h1: main pass, HTTP/1.1 straight to next start. h2: through a local TLS + HTTP/2 proxy (one multiplexed connection). h1c: HTTP/1.1 control runs interleaved with the h2 runs in the same pass."
          },
          {
            "name": "variant",
            "type": "string",
            "description": "Build variant id (see variants.csv)."
          },
          {
            "name": "scenario",
            "type": "string",
            "description": "Navigation scenario: catalog_product, docs_docs or search_search."
          },
          {
            "name": "viewport",
            "type": "string",
            "description": "mobile (390x844, touch) or desktop (1440x900, mouse)."
          },
          {
            "name": "profile",
            "type": "string",
            "description": "fast (unthrottled localhost) or slow4g (150 ms latency, 1.6 Mbps down, 750 kbps up, 4x CPU via CDP)."
          },
          {
            "name": "timing",
            "type": "string",
            "description": "cold: click 50 ms after hydration; warm: click after 2 s without network activity."
          },
          {
            "name": "target",
            "type": "string",
            "description": "URL the click navigates to."
          },
          {
            "name": "ok",
            "type": "boolean",
            "description": "1 when the run completed; 0 when it errored (see error)."
          },
          {
            "name": "error",
            "type": "string",
            "description": "Error message of a failed run."
          },
          {
            "name": "attempts_failed",
            "type": "integer",
            "description": "Failed attempts before this record (runs are retried on resume)."
          },
          {
            "name": "valid",
            "type": "boolean",
            "description": "Completed, target was in the first viewport, no full-page navigation, landed on the target URL. Only valid runs enter summaries."
          },
          {
            "name": "target_in_viewport",
            "type": "boolean",
            "description": "The clicked link's top edge and the click point were inside the viewport (the link intersects it, so it is prefetched)."
          },
          {
            "name": "target_fully_in_viewport",
            "type": "boolean",
            "description": "The whole link box was inside the viewport (p-5 on mobile is a partly visible third-row card)."
          },
          {
            "name": "hard_nav",
            "type": "boolean",
            "description": "A document request followed the click (the router fell back to a full page load)."
          },
          {
            "name": "quiet_reached",
            "type": "boolean",
            "description": "Warm runs: 2 s of network quiet was reached before the 45 s cap."
          },
          {
            "name": "target_url_prefetched",
            "type": "boolean",
            "description": "A non-tree RSC prefetch for the exact target URL was issued before the click."
          },
          {
            "name": "load_ms",
            "type": "number",
            "description": "Start page loadEventEnd (ms from navigation start)."
          },
          {
            "name": "hydrated_ms",
            "type": "number",
            "description": "Start page hydration (first effect of a client component, ms from navigation start)."
          },
          {
            "name": "route_paint_ms",
            "type": "number",
            "description": "Click to first frame showing the destination's URL-independent shell (null for search, which keeps its DOM)."
          },
          {
            "name": "page_paint_ms",
            "type": "number",
            "description": "Click to first frame showing the destination's URL-specific content (params/searchParams resolved)."
          },
          {
            "name": "live_paint_ms",
            "type": "number",
            "description": "Click to first frame showing request-time content (product only: connection() + 300 ms)."
          },
          {
            "name": "complete_ms",
            "type": "number",
            "description": "Click to the last of the scenario's markers painted."
          },
          {
            "name": "route_dom_ms",
            "type": "number",
            "description": "Click to the shell marker's insertion into the DOM (MutationObserver)."
          },
          {
            "name": "page_dom_ms",
            "type": "number",
            "description": "Click to the URL-specific marker's insertion into the DOM."
          },
          {
            "name": "skeleton_ms",
            "type": "number",
            "description": "page_paint_ms - route_paint_ms: how long the shell showed a fallback where the URL-specific content goes (0 when both arrive together)."
          },
          {
            "name": "nav_end_ms",
            "type": "number",
            "description": "Click to the end of the last navigation response (null when the click needed no request)."
          },
          {
            "name": "interaction_ms",
            "type": "number",
            "description": "Event Timing duration of the click interaction (input to next paint), when >= 16 ms."
          },
          {
            "name": "loaf_blocking_ms",
            "type": "number",
            "description": "Sum of long-animation-frame blocking duration between click and complete."
          },
          {
            "name": "prefetch_requests",
            "type": "integer",
            "description": "RSC requests started before the click (all are prefetches)."
          },
          {
            "name": "prefetch_tree_requests",
            "type": "integer",
            "description": "Of those, route-tree requests (next-router-segment-prefetch: /_tree)."
          },
          {
            "name": "prefetch_segment_requests",
            "type": "integer",
            "description": "Of those, segment requests (next-router-segment-prefetch: <segment>)."
          },
          {
            "name": "prefetch_other_requests",
            "type": "integer",
            "description": "Of those, dynamic prefetches (next-router-prefetch 1/2/3 with a state tree, or full prefetches)."
          },
          {
            "name": "prefetch_encoded_bytes",
            "type": "integer",
            "description": "Compressed body bytes of pre-click RSC requests (sum of CDP dataReceived.encodedDataLength)."
          },
          {
            "name": "prefetch_decoded_bytes",
            "type": "integer",
            "description": "Decoded body bytes of pre-click RSC requests."
          },
          {
            "name": "prefetch_inflight_at_click",
            "type": "integer",
            "description": "Pre-click RSC requests still unfinished at the click."
          },
          {
            "name": "js_requests_before",
            "type": "integer",
            "description": "Script requests before the click (start page bundles plus any prefetched chunks)."
          },
          {
            "name": "js_encoded_before",
            "type": "integer",
            "description": "Compressed bytes of those scripts."
          },
          {
            "name": "nav_requests",
            "type": "integer",
            "description": "RSC requests after the click that the navigation waits on (no prefetch header, not Low priority)."
          },
          {
            "name": "nav_encoded_bytes",
            "type": "integer",
            "description": "Compressed body bytes of navigation requests."
          },
          {
            "name": "nav_decoded_bytes",
            "type": "integer",
            "description": "Decoded body bytes of navigation requests."
          },
          {
            "name": "js_requests_after",
            "type": "integer",
            "description": "Script requests after the click (until 500 ms of quiet after complete)."
          },
          {
            "name": "js_encoded_after",
            "type": "integer",
            "description": "Compressed bytes of those scripts."
          },
          {
            "name": "prefetch_requests_after",
            "type": "integer",
            "description": "Prefetch RSC requests after the click (late prefetches or the destination's links)."
          },
          {
            "name": "prefetch_encoded_after",
            "type": "integer",
            "description": "Compressed bytes of those prefetches."
          },
          {
            "name": "rsc_encoded_total",
            "type": "integer",
            "description": "All compressed RSC bytes of the run: prefetch + navigation + later prefetches."
          }
        ],
        "missingValues": [
          ""
        ],
        "primaryKey": [
          "run_id"
        ]
      }
    },
    {
      "name": "variants",
      "path": "variants.csv",
      "title": "Build variants",
      "type": "table",
      "format": "csv",
      "mediatype": "text/csv",
      "encoding": "utf-8",
      "bytes": 986,
      "hash": "sha256:bfce12ddc531a622e2cc20f18b03ffa8b1177918baa5faa09c922d7ebb3b8365",
      "dialect": {
        "header": true,
        "delimiter": ",",
        "lineTerminator": "\r\n",
        "quoteChar": "\"",
        "doubleQuote": true
      },
      "schema": {
        "fields": [
          {
            "name": "variant",
            "type": "string",
            "description": "Variant id."
          },
          {
            "name": "label",
            "type": "string",
            "description": "Short name."
          },
          {
            "name": "description",
            "type": "string",
            "description": "What the variant switches."
          },
          {
            "name": "cache_components",
            "type": "boolean",
            "description": "cacheComponents enabled."
          },
          {
            "name": "partial_prefetching",
            "type": "boolean",
            "description": "partialPrefetching enabled."
          },
          {
            "name": "prefetch_inlining",
            "type": "string",
            "description": "experimental.prefetchInlining: default, false or JSON thresholds (bytes, gzip)."
          },
          {
            "name": "built",
            "type": "boolean",
            "description": "The variant built without errors."
          },
          {
            "name": "measured",
            "type": "boolean",
            "description": "The variant has runs in runs.csv."
          },
          {
            "name": "note",
            "type": "string",
            "description": "Why a variant was not built or measured."
          }
        ],
        "missingValues": [
          ""
        ],
        "primaryKey": [
          "variant"
        ]
      }
    },
    {
      "name": "builds",
      "path": "builds.csv",
      "title": "next build output per variant",
      "type": "table",
      "format": "csv",
      "mediatype": "text/csv",
      "encoding": "utf-8",
      "bytes": 651,
      "hash": "sha256:22ec18631d6e3bb78772bd25876a4ca1c3002b597765aae2cf5d8568f0ca9827",
      "dialect": {
        "header": true,
        "delimiter": ",",
        "lineTerminator": "\r\n",
        "quoteChar": "\"",
        "doubleQuote": true
      },
      "schema": {
        "fields": [
          {
            "name": "variant",
            "type": "string",
            "description": "Variant id."
          },
          {
            "name": "ok",
            "type": "boolean",
            "description": "Build succeeded."
          },
          {
            "name": "build_ms",
            "type": "integer",
            "description": "Wall time of `next build` (one build, same machine; indicative only)."
          },
          {
            "name": "next",
            "type": "string",
            "description": "Next.js version."
          },
          {
            "name": "static_js_files",
            "type": "integer",
            "description": "Files under .next/static ending in .js."
          },
          {
            "name": "static_js_bytes",
            "type": "integer",
            "description": "Their bytes (uncompressed)."
          },
          {
            "name": "html_files",
            "type": "integer",
            "description": "Prerendered .html files under .next/server/app."
          },
          {
            "name": "html_bytes",
            "type": "integer",
            "description": "Their bytes."
          },
          {
            "name": "rsc_files",
            "type": "integer",
            "description": "Prerendered full-route .rsc payloads (excluding segment files)."
          },
          {
            "name": "rsc_bytes",
            "type": "integer",
            "description": "Their bytes."
          },
          {
            "name": "prefetch_rsc_files",
            "type": "integer",
            "description": "Legacy .prefetch.rsc payloads."
          },
          {
            "name": "prefetch_rsc_bytes",
            "type": "integer",
            "description": "Their bytes."
          },
          {
            "name": "segment_files",
            "type": "integer",
            "description": "Per-segment prefetch files (.segments directories)."
          },
          {
            "name": "segment_bytes",
            "type": "integer",
            "description": "Their bytes."
          },
          {
            "name": "dist_bytes",
            "type": "integer",
            "description": "Everything under .next."
          }
        ],
        "missingValues": [
          ""
        ],
        "primaryKey": [
          "variant"
        ]
      }
    },
    {
      "name": "summary_by_variant",
      "path": "summary_by_variant.csv",
      "title": "Per-cell summaries of valid runs",
      "type": "table",
      "format": "csv",
      "mediatype": "text/csv",
      "encoding": "utf-8",
      "bytes": 516277,
      "hash": "sha256:476fd7a3f1b08dfa4038ddd407a74dfd069842f4de99b8d275496543954bbc5e",
      "dialect": {
        "header": true,
        "delimiter": ",",
        "lineTerminator": "\r\n",
        "quoteChar": "\"",
        "doubleQuote": true
      },
      "schema": {
        "fields": [
          {
            "name": "protocol",
            "type": "string",
            "description": "h1 (main pass), h2 or h1c (the h2 arm and its interleaved HTTP/1.1 control); see runs.csv."
          },
          {
            "name": "variant",
            "type": "string",
            "description": "Variant id."
          },
          {
            "name": "scenario",
            "type": "string",
            "description": "Scenario id."
          },
          {
            "name": "viewport",
            "type": "string",
            "description": "mobile or desktop."
          },
          {
            "name": "profile",
            "type": "string",
            "description": "fast or slow4g."
          },
          {
            "name": "timing",
            "type": "string",
            "description": "cold or warm."
          },
          {
            "name": "metric",
            "type": "string",
            "description": "Column of runs.csv (nav_needed = nav_requests > 0)."
          },
          {
            "name": "stat",
            "type": "string",
            "description": "median, or share for boolean metrics."
          },
          {
            "name": "n",
            "type": "integer",
            "description": "Valid runs in the cell with a value for the metric."
          },
          {
            "name": "value",
            "type": "number",
            "description": "Median (type-7 quantile) or share."
          },
          {
            "name": "ci_low",
            "type": "number",
            "description": "95% CI low: seeded percentile bootstrap of the median (10,000 resamples) or Wilson score for shares."
          },
          {
            "name": "ci_high",
            "type": "number",
            "description": "95% CI high."
          },
          {
            "name": "p25",
            "type": "number",
            "description": "25th percentile."
          },
          {
            "name": "p75",
            "type": "number",
            "description": "75th percentile."
          },
          {
            "name": "p95",
            "type": "number",
            "description": "95th percentile (with n around 20, close to the maximum)."
          },
          {
            "name": "mean",
            "type": "number",
            "description": "Arithmetic mean (or share)."
          },
          {
            "name": "diff_vs_p0",
            "type": "number",
            "description": "This variant's median minus P0's in the same cell (share difference for shares)."
          },
          {
            "name": "diff_ci_low",
            "type": "number",
            "description": "95% CI low of the difference: independent two-sample bootstrap, or Newcombe for shares."
          },
          {
            "name": "diff_ci_high",
            "type": "number",
            "description": "95% CI high of the difference."
          }
        ],
        "missingValues": [
          ""
        ]
      }
    },
    {
      "name": "payloads",
      "path": "payloads.csv",
      "title": "What each RSC response carries (one replayed run per variant and scenario)",
      "type": "table",
      "format": "csv",
      "mediatype": "text/csv",
      "encoding": "utf-8",
      "bytes": 17635,
      "hash": "sha256:fc1c7755ec6cb9743a42e4e26800a7fd91c5e49566de73a5d86fea633c1fcf43",
      "dialect": {
        "header": true,
        "delimiter": ",",
        "lineTerminator": "\r\n",
        "quoteChar": "\"",
        "doubleQuote": true
      },
      "schema": {
        "fields": [
          {
            "name": "variant",
            "type": "string",
            "description": "Variant id."
          },
          {
            "name": "scenario",
            "type": "string",
            "description": "Scenario id (desktop, unthrottled, click after 2.5 s)."
          },
          {
            "name": "phase",
            "type": "string",
            "description": "prefetch (before the click) or after_click."
          },
          {
            "name": "kind",
            "type": "string",
            "description": "next-router-segment-prefetch value, prefetch=<next-router-prefetch>, or navigation."
          },
          {
            "name": "url",
            "type": "string",
            "description": "Request path without the _rsc cache-busting parameter."
          },
          {
            "name": "bytes",
            "type": "integer",
            "description": "Uncompressed body length when replayed with accept-encoding: identity."
          },
          {
            "name": "url_content_copies",
            "type": "integer",
            "description": "Occurrences of the URL-specific content marker (data-bench-page)."
          },
          {
            "name": "shared_text_copies",
            "type": "integer",
            "description": "Occurrences of the destination's URL-independent heading text."
          },
          {
            "name": "live_copies",
            "type": "integer",
            "description": "Occurrences of the request-time text (in stock)."
          },
          {
            "name": "flight_roots",
            "type": "integer",
            "description": "Lines that start a Flight root row (0:{...}); 2 means two payloads in one response."
          }
        ],
        "missingValues": [
          ""
        ]
      }
    },
    {
      "name": "summary",
      "path": "summary.json",
      "title": "Headline numbers, chart rows and provenance",
      "format": "json",
      "mediatype": "application/json",
      "encoding": "utf-8",
      "bytes": 187500,
      "hash": "sha256:2b5f500d82d8b4e98d6497257892b96d0af105855f37219de5054f30c215ae61"
    }
  ]
}
