Spokes.wiki Search About

webperf-wiki

log

Synthesis

The evolving thesis. Current best understanding of this wiki’s topic, updated on every ingest.

Current thesis

This wiki covers web performance and page-weight minimalism. The founding provocation, landing-page-14kb, makes the case that a complete, accessible, production-grade landing page fits in 14 KB (one TCP slow-start window, <50 ms render) against a ~2,600 KB median web page — by dropping JS entirely, using system fonts, and inlining SVG. The implied thesis: most web bloat is optional, and the usable floor is far lower than common practice.

The baseline is now measured, and it corroborates the provocation. page-weight is no longer a single advocacy claim: the web-almanac (HTTP Archive, neutral field data) puts the median page at 2,652 KB desktop / 2,311 KB mobile (web-almanac-page-weight-2024) — independently confirming the “2,600 KB” figure the 14 KB piece used as its foil, and showing it is still growing (+7% YoY; ~357% over a decade for mobile). Composition: images ≈1,054 KB, JS ≈613 KB and now the most-requested file type, fonts ≈131 KB, CSS ≈78 KB, HTML ≈18 KB. So bloat is real, optional, and JS-led — exactly where bundle-size and squint aim.

Brought to the current edition on 2026-08-12 (web-almanac-page-weight-2025, July 2025 crawl). The trend did not merely continue, it steepened: median home page +7.8% year over year, mobile +8.4%, mobile inner pages +9.5%, and the authors state the growth is accelerating since October 2024. Median video bytes rose 28% in a single year. Composition held its shape — images 911 KB, JavaScript 632 KB on the median mobile home page — so the JS-led reading survives a second edition rather than resting on one.

Two things this changes about the argument. First, the growth ran straight through a period in which core-web-vitals were an established ranking input and inp had already replaced FID, so the industry got a measured, business-facing incentive to reduce weight and the weight went up anyway. Any account of why bloat persists (edge 2) has to survive that fact; “nobody had a reason to care” no longer does. Second, the 90th percentile is where the real argument lives — 1.9 MB of mobile JavaScript, 6.3 MB of images, 1.0 MB of it unused — against a median that looks almost tractable.

And the baseline is less precise than this wiki has been treating it. The 2025 chapter states the median mobile home page as 2,362 KB, as 2.6 MB, and as 2.56 MB, in three places, without reconciling them. Quote it as a range (~2.4–2.6 MB mobile, ~2.7–2.9 MB desktop) and lean on the growth rate, which is consistent. Every “the median page weighs X” claim in this domain descends from this chapter, and none of them carries the range — including, until now, ours.

Why minimize at all? The SEO/business case is now partly mapped. The report core-web-vitals-seo traces how performance touches search: Google’s core-web-vitals (LCP/INP/CLS, measured on real users via CrUX) are a confirmed but minor ranking factor — a quality baseline and tie-breaker that avoids a penalty rather than driving visibility (a 2025 study of 107k pages found only r ≈ −0.12…−0.18 between LCP and search presence). The larger payoff is indirect (lower bounce, more engagement/conversions). So byte minimalism helps SEO only insofar as it improves real-user Core Web Vitals, and even then the direct ranking benefit is capped at “good.” Minimalism is better justified by UX/cost/resilience than by raw rankings. The responsiveness vital, inp (Interaction to Next Paint), replaced FID in March 2024 and sharpens the JS critique: it scores all interactions (good ≤200 ms / poor

500 ms) by input delay → processing → presentation, so JS is not only load weight but where the main thread is felt. For interactive apps the binding constraint shifts from transfer bytes to main-thread execution — a partial answer to whether the 14 KB floor matters beyond static pages: for apps the lever moves from bytes to execution.

Lab vs. field — what actually gets measured. Two tools anchor the chain. lighthouse is a single synthetic load (lab data); crux (Chrome UX Report) is the p75 / 28-day distribution of real Chrome users — and only CrUX feeds Search. A great lab score is not a good field score, which is the measurement-side of the page-weight-vs-architecture tension: because CrUX scores executed experience, equal-byte pages can post different CrUX numbers (delivery codec, main-thread cost). CrUX carries its own caveat the crawl-based web-almanac lacks — eligibility needs publicly discoverable pages with significant Chrome traffic, so it is the best public field signal, not a census. Net the chain is end-to-end: author bytes → delivery/execution → CrUX field metrics → ranking. Diagnose with Lighthouse, judge with CrUX. The instrument under all of this is Google’s web-vitals JS library (~2 KB): it measures the same metrics on a site’s own real users, matching how Chrome reports to CrUX/PSI — so the field side isn’t only Google’s aggregate window, a team can run its own RUM, and crucially it covers the long-tail and pre-launch pages CrUX’s popularity threshold omits. Its attribution build adds root-cause data, so the “diagnose vs. judge” split softens: you can now diagnose in the field, not only in the lab.

Three layers of minimization are now in view. landing-page-14kb minimizes by hand-authoring less (a static-page lever); squint minimizes by changing the compiler so a high-level source language emits small JS (a tooling/language lever); and a delivery layer minimizes the bytes you ship regardless of what you authored. On that delivery layer, brotli (RFC 7932, Google) beats gzip on text for free and directly answers the standing “why is basic optimization under-adopted?” question — the Almanac finds only ~70% of pages use any text compression, so the same authored bytes transfer at very different sizes depending on codec. avif is the image analog and the single highest-leverage saving, since images (~1,054 KB) are the largest slice of the median page; modern royalty-free formats beat JPEG/WebP at ~93% browser support. So author-side levers reduce bytes you write; delivery-side levers reduce bytes you ship them as. Generalizing across the author/tooling layers, bundle-size is the JS-app-era successor to page weight, and its levers are: ship less code you wrote, ship less runtime, and emit tree-shakeable modules. Squint is also the first source to address interactive/app code rather than static pages, and it begins to engage the open question of whether the tight byte floor survives beyond static landing pages — by tooling toward it rather than hand-authoring.

From feat to discipline: budgets and two byte layers. Minimalism need not be a one-off heroic page — performance-budget (performance-budgets-101) turns “ship fewer bytes” into a CI gate (Lighthouse CI / bundlesize). It also reveals three nested byte targets: the 14 KB first-RTT floor (landing-page-14kb), web.dev’s 170 KB compressed critical-path budget over 3G, and the 2,652 KB median reality. These aren’t in conflict — they’re the same idea at different scopes (first packet → critical path → whole page).

The thesis splits into a first-party and a third-party layer. Hand-authoring less (landing-page-14kb), smaller bundles (bundle-size/squint), and budgets all govern first-party bytes. But web-almanac-third-parties-2024 shows 92% of pages load third parties (popular sites a median of 66), mostly scripts (30.5%), with Google owning 5 of the top-10 domains and a median inclusion-chain depth of 3.4 — much third-party weight is indirect, never chosen by the author. So third-party-resources are a separate, governance/consent problem that first-party minimalism can’t reach; a budget can cap their count but enforcement is organizational, not just a build flag.

The execution axis gets its own concept, and a contrarian twist. The synthesis kept pointing at main-thread execution — inp measures it, Total Blocking Time sums it — without a page for the thing itself. when-to-block-main-thread (Smashing Magazine) supplies it: the main-thread runs a page’s JS, layout, paint, and input on one thread, bounded by a 16.6 ms frame budget and the 50 ms “long task” line above which it stops servicing input. That’s the “executing less” half of web-performance made concrete, and it sharpens the same claim inp made — cut bundle-size and the main thread has less to run. But the article also complicates the wiki’s reflexes. The obvious performance move is to push heavy work off the main thread onto a Web Worker; Ayomipo shows the thread boundary has its own price — postMessage copies its payload with the Structured Clone Algorithm, a synchronous O(n) deep copy — so for data-bound work (a big payload, light processing) the copy can cost more than the work, and keeping it on the main thread is faster. Offloading only wins for CPU-bound work where processing dwarfs transfer; transferable objects (zero-copy ownership handoff, ~43× on a 32 MB payload) narrow but don’t erase the gap. So the rule isn’t “never block the main thread” but “never block it for too long,” and “less work” now has a placement dimension, not only an amount: the same computation costs differently depending on which thread runs it — the execution-side echo of the delivery-side lesson that equal-byte pages differ on executed cost.

Sources now include a provocation (landing-page-14kb), a synthesized report, a tooling exemplar (squint, README claims), neutral HTTP Archive field data (web-almanac chapters), and vendor guidance (performance-budgets-101). The neutral data has moved the page-weight baseline from hypothesis to established finding; the floor itself remains a hypothesis to test.

The instrument acquired a second audience (2026-08-12)

Re-reading lighthouse found a fifth audit category, Agentic browsing — deterministic audits of “how well your site is constructed for machine interaction”: WebMCP tool registration and schema validity, accessibility-tree quality for machine navigation, llms.txt discoverability, and layout stability via CLS. The tool this wiki has treated as its performance instrument now also grades pages for AI agents.

That is a change in what this spoke is measuring against, not just a docs update. Every argument here runs from bytes and main-thread time to a human’s experience of a page, judged in the field by crux and in the lab by lighthouse. A category scoring machine-readability shares the instrument and not the goal, and in one place it shares the metric: CLS now carries two justifications — don’t move content under a reader’s eyes, and don’t move it under an agent’s selector. Nothing here establishes that those two want the same threshold, and the corpus holds no source that has asked.

This settles less than it might appear to. It does not show that agent traffic is displacing human traffic, or that byte minimalism helps or hurts machine readers — no source here measures either. What it does show is that Google has begun shipping the assumption inside the default measurement tool, which is how the core-web-vitals-seo thesis got its leverage in the first place: the incentive followed the instrument. The honest reading is that this is an early signal, and the spoke should watch whether an agentic score ever acquires a ranking consequence the way Core Web Vitals did.

The seam runs to ../search-marketing-wiki (llms-txt, generative-engine-optimization) and to ../agentic-tooling-wiki (webmcp, paged the same day) rather than into this spoke.

Open questions

  • Does the 14 KB floor hold for interactive apps, or only static landing pages? (squint is a tooling-side bet that small bundles are reachable for app code — but how small, measured, vs. a plain-JS or full-ClojureScript baseline?)
  • Language/tooling-level minimalism (squint) vs. hand-authoring minimalism (landing-page-14kb): which gives more byte savings per unit of effort, and do they compose?
  • How much of typical bloat is analytics / third-party scripts vs. first-party code? Partly answered (web-almanac-third-parties-2024): third parties are on 92% of pages, are mostly scripts, and arrive via deep inclusion chains — a structural slice of page-weight, not a rounding error. Remaining: a clean first-party-vs-third-party byte split (the chapter gives prevalence/requests more than a definitive byte share).
  • What is lost (if anything) at this floor — A/B testing, personalization, tracking? (Much of that is the third-party-resources layer — so the cost of the floor is partly the cost of dropping third parties.)
  • If Core Web Vitals ranking benefit plateaus at “good,” how low do bytes actually need to go for SEO — i.e. where’s the point of diminishing SEO returns vs. UX returns?
  • Why is basic optimization under-adopted? The Almanac finds only ~70% of pages use text compression and minification has fallen since 2022 (web-almanac-page-weight-2024) — is the obstacle tooling defaults, third-party injection, or incentives?
  • On the execution axis (main-thread): where’s the crossover between offloading to a worker and keeping work on the main thread? when-to-block-main-thread gives the shape of the answer (CPU-bound → offload, data-bound → keep; measure it) but not a general threshold — and how does chunking/yielding (scheduler.yield, isInputPending) change the calculus vs a hard offload?

Growth edges

Ranked; each names the kind of source that would close it (see ../QUALITY.md → Growth edges).

  1. A clean first-party versus third-party byte split. web-almanac-third-parties-2024 gives prevalence and request counts; the byte share is what the page-weight argument actually needs. — needs: HTTP Archive or Almanac data reporting bytes by party.
  2. Why basic optimization is under-adopted. Only ~70% of pages use text compression and minification has fallen since 2022 — a finding with no explanation attached, and web-almanac-page-weight-2025 sharpens it: weight kept climbing through a period when Core Web Vitals were a live ranking input, so the explanation cannot be that nobody had an incentive. — needs: a T1/T2 study of tooling defaults or injection paths.
  3. Does the 14 KB floor hold for interactive apps? The spoke’s founding claim is demonstrated on static pages; squint is a bet that app code can get there. — needs: a measured app-code baseline against plain JS.

Coverage edges (added 2026-08-08, at the curator’s request for a wider backlog). These widen what the spoke covers instead of answering an open question above; one ordinary solid source closes any.

  1. Fonts. Images have avif and mdn-image-types; fonts, routinely the second-heaviest asset on a page, have nothing on subsetting, font-display or variable fonts. — needs: web.dev or MDN guidance plus one Almanac chapter for the numbers.
  2. The transport layer. The spoke measures bytes and ignores how they arrive: HTTP/2 versus HTTP/3, compression negotiation past brotli, caching headers, early hints, CDN placement. The 14 KB floor in landing-page-14kb is itself a transport fact (the initial congestion window) that no page explains. — needs: an RFC-level or web.dev explainer, plus one measured deployment.
  3. How anyone knows: RUM versus synthetic. Half closed 2026-08-12 — the CrUX methodology docs were read for method, and crux now carries the collection rules (the three opt-in conditions, the mechanical noindex/HTTP-200 eligibility test, the undisclosed popularity threshold) and the named exclusions that bound the field side: Chrome on iOS, Android WebView, other Chromium browsers including Edge. What is still missing is the comparison as a subject — why a lab score and a field score disagree, stated somewhere other than as a caveat on two tool pages. — needs: a methodology write-up from a field-data provider, or a measured lab-vs-field divergence study.
  4. The hydration bill. bundle-size covers bytes shipped; nothing covers the cost of waking that JavaScript up, which is where the modern framework debate (islands, RSC, resumability) actually sits. — needs: a measured comparison, not a framework’s own launch post.
  5. WebMCP (added and CLOSED 2026-08-12, hours apart). webmcp now lives in ../agentic-tooling-wiki, written from the W3C Web Machine Learning CG explainer plus Chrome’s own docs (both T1) and linked cross-wiki, as predicted. The fact that came back for this spoke: the audit shipped ahead of the standard — WebMCP is a proposal in origin trial from Chrome 149, no version number, 108 open issues, and Lighthouse scores pages against it already. Every other Lighthouse category audits something settled, which is a reason to treat the Agentic browsing score as a moving target rather than a benchmark.

Contradictions

  • Page weight vs. architecture (cross-wiki). This wiki’s premise — fewer bytes → faster → better — meets a counter-claim tracked in static-site-wiki: real-world core-web-vitals are driven by architecture and delivery as much as payload size (HTTP Archive field data: bytes correlate with LCP but are not the dominant factor; CLS barely correlates with bytes; Shopify is heaviest yet fast). Reconciliation: bytes are necessary-but-not-sufficient. Minimalism still helps, but is not the whole game. This wiki’s own web-almanac-page-weight-2024 now reinforces the delivery side from the same HTTP Archive corpus: only ~70% of pages use text compression and the 90th-pctile mobile Total Blocking Time is 5,786 ms — i.e. how bytes are compressed and executed swings real-user metrics as much as the byte count, so both lenses read the same field data and agree on “necessary-but-not-sufficient.”

Index

Catalog of every wiki page, grouped by schema.org @type. Read this first when answering a query, then drill into the relevant pages. Updated on every ingest.

BlogPosting (sources)

  • landing-page-14kb — shipping a working landing page in 14 KB / web-perf minimalism · source

DefinedTerm

  • web-performanceumbrella: load/response speed via shipping less + executing less; the byte layers, the measurement chain, and budgets · domain
  • page-weight — total bytes a page downloads; the wiki’s founding concept + measured baseline · concept
  • bundle-size — JS-app byte weight; the app-era successor to page weight, and its levers · concept
  • third-party-resources — analytics/ads/embeds you use but don’t author; 92% of pages · concept
  • performance-budget — enforced byte/timing limits that gate the build; minimalism as discipline · practice
  • core-web-vitals — Google’s CrUX field metrics (LCP/INP/CLS); the SEO + perf yardstick · standard
  • inp — Interaction to Next Paint; the responsiveness Core Web Vital (replaced FID Mar 2024); ≤200ms good · source · standard
  • main-thread — the single browser thread running JS/layout/paint/input; the 16.6ms frame budget + 50ms long-task line; the “executing less” axis where inp/TBT live · concept
  • web-worker — background thread for offloading heavy work; shared-nothing → postMessage structured-clone cost, and transferable objects (zero-copy) as the escape · mechanism
  • brotli — RFC 7932 lossless text codec (Google); beats gzip on HTML/CSS/JS; the delivery-side byte lever · source · mechanism
  • avif — modern royalty-free image format; beats JPEG/WebP on the biggest page-weight slice · source · mechanism

SoftwareApplication (tools)

  • lighthouse — Google’s open-source page-audit tool; lab data (LCP/TBT/CLS), 0–100 scores; lab-vs-field caveat · source
  • web-vitals — Google’s ~2 KB JS library for first-party RUM of Core Web Vitals (onLCP/onINP/onCLS/onFCP/onTTFB); attribution build for field diagnosis; the instrument behind CrUX/PSI · source

Dataset

  • crux — Chrome UX Report; real-user (field) Core Web Vitals at p75/28-day; Google Search’s actual signal; lab-vs-field anchor · source

Periodical

  • web-almanac — HTTP Archive’s annual data-driven report; the wiki’s neutral field-data baseline

Report

  • core-web-vitals-seo — how Core Web Vitals affect SEO: confirmed but minor ranking factor
  • web-almanac-page-weight-2025the current edition (July 2025 crawl, published Jan 2026): median home page +7.8% YoY and accelerating, mobile inner pages +9.5%, video bytes +28%; median mobile 911 KB images / 632 KB JS; 90th percentile 1.9 MB JS with 1.0 MB unused — and the chapter states its own mobile median three incompatible ways · source · T1
  • web-almanac-page-weight-2024 — HTTP Archive median page weight + resource breakdown; kept for the series · source
  • web-almanac-third-parties-2024 — prevalence/weight of third parties; Google’s dominance · source

TechArticle (sources)

  • performance-budgets-101 — web.dev’s primer on performance budgets and their enforcement · source

  • web-dev-compress-images-avif — web.dev’s AVIF encoder guide; “>50% vs JPEG”, features (HDR/film grain), the encode-cost tradeoff · source

  • mdn-image-types — MDN image-format reference; AVIF = AV1-in-HEIF, 50% vs 30% (WebP), transparency/animation, no progressive render · source

  • web-dev-vitals — web.dev’s Web Vitals overview; LCP/INP/CLS thresholds, p75 rule, TTFB/FCP supporting metrics · source

  • web-dev-third-party-js — web.dev on loading third-party JS; async/defer, preconnect, lazy-load, no document.write · source

  • when-to-block-main-thread — Smashing Magazine (Victor Ayomipo): “never block the main thread for too long” — the worker/postMessage boundary has its own cost, so data-bound work can be faster on the main thread; CPU-bound vs data-bound framework · source · T2

SoftwareSourceCode (sources)

  • squint — light-weight ClojureScript dialect; compiles to small native-JS bundles · source

Organization

  • smashing-magazine — front-end/web-design technical publication; publisher of the main-thread piece · publisher

Person

  • victor-ayomipo — front-end dev; author of the main-thread article (from debugging his Fastary screenshot extension)

Synthesis

  • synthesis — the evolving thesis (open questions + flagged contradictions)