This page reports reproducible measurements for the deployable production build and its component development system. Every number comes from generated build output, test results, or metadata — not fabricated values or historical reports. Performance figures are lab measurements of the built static output; they are not production Core Web Vitals or live-network measurements.
Quality overview
Routes
25generated HTML pagesStorybook stories
3128 component + 3 foundationA11y tests
319319 passed · 0 failed · 0 skippedRoute a11y tests
88 passingStorybook a11y tests
2828 passingProduction JS (static)
1.2 MB330.8 KB gzip · 19 filesPer-route JS (from HTML)
1.2 KBreferenced by each normal page (single shared bundle)Production CSS
155.7 KB13 stylesheetsStorybook isolated
Yes0 Storybook references in production JS/CSSPerformance
Lighthouse measures the deployable production build (the static output in dist/) by serving it through a temporary local server during the build pipeline. The route labels below are paths on that built site. These are lab measurements of the deployment candidate, not production Core Web Vitals and not live-network performance.
/404.html/
Measured: 8/10/2026, 3:21:30 PM· Device: mobile · Throttling: simulate
Performance
74/ 100Accessibility
100/ 100Best Practices
100/ 100SEO
66/ 100LCP
1.8 sLargest Contentful PaintCLS
0.019Cumulative Layout ShiftTBT
1.3 sTotal Blocking TimeFCP
1.7 sFirst Contentful Paint/about/
Measured: 8/10/2026, 3:21:43 PM· Device: mobile · Throttling: simulate
Performance
98/ 100Accessibility
100/ 100Best Practices
100/ 100SEO
100/ 100LCP
1.7 sLargest Contentful PaintCLS
0.064Cumulative Layout ShiftTBT
—Total Blocking TimeFCP
1.7 sFirst Contentful Paint/blog/
Measured: 8/10/2026, 3:22:30 PM· Device: mobile · Throttling: simulate
Performance
97/ 100Accessibility
100/ 100Best Practices
100/ 100SEO
100/ 100LCP
2.3 sLargest Contentful PaintCLS
0.010Cumulative Layout ShiftTBT
—Total Blocking TimeFCP
1.8 sFirst Contentful Paint/blog/250mm-trading-card-box/
Measured: 8/10/2026, 3:21:55 PM· Device: mobile · Throttling: simulate
Performance
96/ 100Accessibility
100/ 100Best Practices
100/ 100SEO
100/ 100LCP
2.6 sLargest Contentful PaintCLS
0.036Cumulative Layout ShiftTBT
—Total Blocking TimeFCP
1.5 sFirst Contentful Paint/blog/better-agent-results-start-with-better-context/
Measured: 8/10/2026, 3:22:07 PM· Device: mobile · Throttling: simulate
Performance
95/ 100Accessibility
100/ 100Best Practices
100/ 100SEO
100/ 100LCP
2.6 sLargest Contentful PaintCLS
0.033Cumulative Layout ShiftTBT
—Total Blocking TimeFCP
2.1 sFirst Contentful Paint/blog/good-agent-context-is-carved-not-copied/
Measured: 8/10/2026, 3:22:18 PM· Device: mobile · Throttling: simulate
Performance
93/ 100Accessibility
100/ 100Best Practices
100/ 100SEO
100/ 100LCP
2.8 sLargest Contentful PaintCLS
0.025Cumulative Layout ShiftTBT
—Total Blocking TimeFCP
2.3 sFirst Contentful Paint/blog/why-do-i-need-all-this-usb-and-sd-media-holder/
Measured: 8/10/2026, 3:22:42 PM· Device: mobile · Throttling: simulate
Performance
98/ 100Accessibility
100/ 100Best Practices
100/ 100SEO
100/ 100LCP
2.4 sLargest Contentful PaintCLS
0.033Cumulative Layout ShiftTBT
—Total Blocking TimeFCP
1.4 sFirst Contentful Paint/contact/
Measured: 8/10/2026, 3:22:53 PM· Device: mobile · Throttling: simulate
Performance
99/ 100Accessibility
100/ 100Best Practices
100/ 100SEO
100/ 100LCP
1.7 sLargest Contentful PaintCLS
0.010Cumulative Layout ShiftTBT
—Total Blocking TimeFCP
1.7 sFirst Contentful Paint/
Measured: 8/10/2026, 3:23:04 PM· Device: mobile · Throttling: simulate
Performance
96/ 100Accessibility
100/ 100Best Practices
100/ 100SEO
100/ 100LCP
2.3 sLargest Contentful PaintCLS
0.078Cumulative Layout ShiftTBT
—Total Blocking TimeFCP
1.8 sFirst Contentful Paint/lab/context/
Measured: 8/10/2026, 3:23:16 PM· Device: mobile · Throttling: simulate
Performance
97/ 100Accessibility
100/ 100Best Practices
100/ 100SEO
63/ 100LCP
2.0 sLargest Contentful PaintCLS
0.073Cumulative Layout ShiftTBT
—Total Blocking TimeFCP
2.0 sFirst Contentful Paint/lab/site-inventory/
Measured: 8/10/2026, 3:23:27 PM· Device: mobile · Throttling: simulate
Performance
98/ 100Accessibility
87/ 100Best Practices
96/ 100SEO
54/ 100LCP
1.8 sLargest Contentful PaintCLS
0.056Cumulative Layout ShiftTBT
—Total Blocking TimeFCP
1.8 sFirst Contentful Paint/lab/youtube-facade-test/
Measured: 8/10/2026, 3:23:39 PM· Device: mobile · Throttling: simulate
Performance
100/ 100Accessibility
98/ 100Best Practices
96/ 100SEO
54/ 100LCP
1.8 sLargest Contentful PaintCLS
—Cumulative Layout ShiftTBT
—Total Blocking TimeFCP
0.9 sFirst Contentful Paint/portfolio/
Measured: 8/10/2026, 3:24:02 PM· Device: mobile · Throttling: simulate
Performance
93/ 100Accessibility
100/ 100Best Practices
100/ 100SEO
100/ 100LCP
2.3 sLargest Contentful PaintCLS
0.098Cumulative Layout ShiftTBT
—Total Blocking TimeFCP
2.2 sFirst Contentful Paint/portfolio/design-system/
Measured: 8/10/2026, 3:23:50 PM· Device: mobile · Throttling: simulate
Performance
99/ 100Accessibility
100/ 100Best Practices
100/ 100SEO
100/ 100LCP
1.5 sLargest Contentful PaintCLS
0.069Cumulative Layout ShiftTBT
—Total Blocking TimeFCP
1.5 sFirst Contentful Paint/portfolio/site-quality/
Measured: 8/10/2026, 3:24:13 PM· Device: mobile · Throttling: simulate
Performance
90/ 100Accessibility
100/ 100Best Practices
100/ 100SEO
100/ 100LCP
2.7 sLargest Contentful PaintCLS
0.093Cumulative Layout ShiftTBT
—Total Blocking TimeFCP
2.7 sFirst Contentful Paint/posts/3d-printing/250mm-trading-card-box/
Measured: 8/10/2026, 3:24:26 PM· Device: mobile · Throttling: simulate
Performance
92/ 100Accessibility
100/ 100Best Practices
100/ 100SEO
100/ 100LCP
2.9 sLargest Contentful PaintCLS
0.028Cumulative Layout ShiftTBT
—Total Blocking TimeFCP
2.4 sFirst Contentful Paint/posts/3d-printing/why-do-i-need-all-this-usb-and-sd-media-holder/
Measured: 8/10/2026, 3:24:38 PM· Device: mobile · Throttling: simulate
Performance
93/ 100Accessibility
100/ 100Best Practices
96/ 100SEO
100/ 100LCP
2.9 sLargest Contentful PaintCLS
0.025Cumulative Layout ShiftTBT
—Total Blocking TimeFCP
2.2 sFirst Contentful Paint/search/
Measured: 8/10/2026, 3:24:49 PM· Device: mobile · Throttling: simulate
Performance
96/ 100Accessibility
100/ 100Best Practices
100/ 100SEO
66/ 100LCP
2.6 sLargest Contentful PaintCLS
0.007Cumulative Layout ShiftTBT
—Total Blocking TimeFCP
1.9 sFirst Contentful Paint/speaking/
Measured: 8/10/2026, 3:25:01 PM· Device: mobile · Throttling: simulate
Performance
95/ 100Accessibility
100/ 100Best Practices
100/ 100SEO
100/ 100LCP
2.5 sLargest Contentful PaintCLS
0.040Cumulative Layout ShiftTBT
—Total Blocking TimeFCP
2.0 sFirst Contentful Paint/tags/
Measured: 8/10/2026, 3:25:58 PM· Device: mobile · Throttling: simulate
Performance
98/ 100Accessibility
100/ 100Best Practices
100/ 100SEO
100/ 100LCP
1.8 sLargest Contentful PaintCLS
0.020Cumulative Layout ShiftTBT
—Total Blocking TimeFCP
1.8 sFirst Contentful Paint/tags/3d-printing/
Measured: 8/10/2026, 3:25:12 PM· Device: mobile · Throttling: simulate
Performance
99/ 100Accessibility
100/ 100Best Practices
100/ 100SEO
100/ 100LCP
2.2 sLargest Contentful PaintCLS
0.050Cumulative Layout ShiftTBT
—Total Blocking TimeFCP
1.1 sFirst Contentful Paint/tags/ai-agents/
Measured: 8/10/2026, 3:25:35 PM· Device: mobile · Throttling: simulate
Performance
98/ 100Accessibility
100/ 100Best Practices
100/ 100SEO
69/ 100LCP
2.1 sLargest Contentful PaintCLS
0.013Cumulative Layout ShiftTBT
—Total Blocking TimeFCP
1.8 sFirst Contentful Paint/tags/ai/
Measured: 8/10/2026, 3:25:23 PM· Device: mobile · Throttling: simulate
Performance
98/ 100Accessibility
100/ 100Best Practices
100/ 100SEO
69/ 100LCP
2.1 sLargest Contentful PaintCLS
0.013Cumulative Layout ShiftTBT
—Total Blocking TimeFCP
1.8 sFirst Contentful Paint/tags/documentation/
Measured: 8/10/2026, 3:25:46 PM· Device: mobile · Throttling: simulate
Performance
99/ 100Accessibility
100/ 100Best Practices
100/ 100SEO
69/ 100LCP
2.1 sLargest Contentful PaintCLS
0.010Cumulative Layout ShiftTBT
—Total Blocking TimeFCP
1.1 sFirst Contentful Paint/tags/software-development/
Measured: 8/10/2026, 3:26:09 PM· Device: mobile · Throttling: simulate
Performance
97/ 100Accessibility
100/ 100Best Practices
100/ 100SEO
69/ 100LCP
2.1 sLargest Contentful PaintCLS
0.075Cumulative Layout ShiftTBT
—Total Blocking TimeFCP
1.8 sFirst Contentful PaintThe CI pipeline enforces a Lighthouse performance budget: performance ≥ 95, accessibility ≥ 95, SEO ≥ 100, best-practices ≥ 95. See lighthouserc.js.
Production bundle
Bundle figures are from the Astro-only production build in dist/. Storybook assets under /design-system/lab/ are measured separately and are never loaded by ordinary site pages.
JavaScript files present in the deployment
These are all JavaScript files present in dist/ (source maps excluded). Not every file is loaded by every route. See the route-measurement tables below for per-page behavior.
| Category | Total bytes | Files |
|---|---|---|
| Astro page scripts | 744.5 KB | 9 |
| Pagefind search index and UI | 430.9 KB | 6 |
| Partytown analytics offloading | 94.1 KB | 4 |
| Total | 1.2 MB | 19 |
All JavaScript files present in the Astro-only dist/ directory (source maps excluded). Not all files are loaded by every route. See routeMeasurements below for per-page loading behavior.
Route-level JavaScript references
Each row shows which JavaScript assets a route’s generated HTML references, their total size, and estimated inline script bytes.
| Route | Referenced JS | Total bytes | Inline script bytes | Features |
|---|---|---|---|---|
/ | <code>js?id=G-70E1BWCFJ3</code> | 0 B | 5.8 KB | core |
/blog/ | <code>js?id=G-70E1BWCFJ3</code> | 0 B | 5.9 KB | core |
/portfolio/ | <code>js?id=G-70E1BWCFJ3</code>, <code>YouTubeFacade.astro_astro_type_script_index_0_lang.BKBlQNWG.js</code> | 1.2 KB | 6.1 KB | core |
/portfolio/design-system/ | <code>js?id=G-70E1BWCFJ3</code> | 0 B | 6.2 KB | core |
/portfolio/site-quality/ | <code>js?id=G-70E1BWCFJ3</code> | 0 B | 6.2 KB | core |
/blog/better-agent-results-start-with-better-context/ | <code>js?id=G-70E1BWCFJ3</code>, <code>ec.0vx5m.js</code> | 2.5 KB | 9.1 KB | core |
/search/ | <code>js?id=G-70E1BWCFJ3</code> | 0 B | 6.0 KB | core |
/contact/ | <code>js?id=G-70E1BWCFJ3</code> | 0 B | 8.3 KB | core |
Full asset details by route
/
| Asset | Bytes | Category |
|---|---|---|
https://www.googletagmanager.com/gtag/js?id=G-70E1BWCFJ3 | 0 B | core |
Inline script bytes: 5.8 KB
/blog/
| Asset | Bytes | Category |
|---|---|---|
https://www.googletagmanager.com/gtag/js?id=G-70E1BWCFJ3 | 0 B | core |
Inline script bytes: 5.9 KB
/portfolio/
| Asset | Bytes | Category |
|---|---|---|
https://www.googletagmanager.com/gtag/js?id=G-70E1BWCFJ3 | 0 B | core |
/_astro/YouTubeFacade.astro_astro_type_script_index_0_lang.BKBlQNWG.js | 1.2 KB | core |
Inline script bytes: 6.1 KB
/portfolio/design-system/
| Asset | Bytes | Category |
|---|---|---|
https://www.googletagmanager.com/gtag/js?id=G-70E1BWCFJ3 | 0 B | core |
Inline script bytes: 6.2 KB
/portfolio/site-quality/
| Asset | Bytes | Category |
|---|---|---|
https://www.googletagmanager.com/gtag/js?id=G-70E1BWCFJ3 | 0 B | core |
Inline script bytes: 6.2 KB
/blog/better-agent-results-start-with-better-context/
| Asset | Bytes | Category |
|---|---|---|
https://www.googletagmanager.com/gtag/js?id=G-70E1BWCFJ3 | 0 B | core |
/_astro/ec.0vx5m.js | 2.5 KB | core |
Inline script bytes: 9.1 KB
/search/
| Asset | Bytes | Category |
|---|---|---|
https://www.googletagmanager.com/gtag/js?id=G-70E1BWCFJ3 | 0 B | core |
Inline script bytes: 6.0 KB
/contact/
| Asset | Bytes | Category |
|---|---|---|
https://www.googletagmanager.com/gtag/js?id=G-70E1BWCFJ3 | 0 B | core |
Inline script bytes: 8.3 KB
Feature-specific assets
| Feature | Deployment bytes | Routes requesting | Loading behavior |
|---|---|---|---|
| Pagefind (search) | 430.9 KB | none | Loaded only on /search/. Not requested by other routes. |
| Partytown (analytics) | 94.1 KB | none | Script loader present in HTML head on most pages. Worker scripts load lazily on user interaction. |
| Turnstile (contact form) | External | none | Loaded only on /contact/. Cloudflare external asset. |
| Storybook lab | 7.5 MB | none | Not requested by any normal page. Only available at /design-system/lab/. |
Component lab (Storybook)
The Storybook application at /design-system/lab/ is a separate application. Its JavaScript is not loaded by ordinary blog pages. The isolation verification below confirms this.
| Metric | Value |
|---|---|
| Total JavaScript | 7.5 MB |
| Total JavaScript (gzip) | 1.9 MB |
| Files | 46 |
Largest Storybook chunks
| Chunk | Size | Category |
|---|---|---|
/sb-manager/globals-runtime.js | 3.1 MB | manager UI |
/sb-manager/runtime.js | 1.2 MB | manager UI |
/_astro/iframe-DhapBL6U.js | 807.3 KB | iframe bundle |
/_astro/axe-CU0zJHZz.js | 565.6 KB | a11y addon (axe-core) |
/_astro/components-Q0HZ7DLQ.js | 558.1 KB | other |
Storybook isolation
Storybook is built as a separate static application and copied intodist/design-system/lab/ during deployment. It is not part of the Astro build graph and is not imported by any production component.
| Check | Result |
|---|---|
Storybook assets isolated to /design-system/lab/ | ✅ |
| Static scan: Storybook references in production JS/CSS | 0 found (clean) |
| Network test: ordinary pages loading Storybook assets | 0 (verified via Playwright) |
static scan of JS/CSS files excluding dist/design-system/lab/ and confirmed by Playwright network-interception tests in tests/storybook-isolation.spec.ts.
The Storybook bundle is approximately 7.5 MB(uncompressed). This is the weight of a design-system development tool, not the blog. It is served only to users who explicitly visit/design-system/lab/.
Accessibility verification
Automated accessibility checks run against every Storybook component story and every primary site route. The tests use axe-core through Playwright. Results come from the last pnpm test:e2e run.
| Scope | Tests | Passed | Failed | Skipped |
|---|---|---|---|---|
| All a11y tests | 319 | 319 | 0 | 0 |
| Storybook component stories | 28 | 28 | 0 | — |
| Site routes | 8 | 8 | 0 | — |
What remains manual
Automated checks only. Keyboard flow, screen-reader behavior, content clarity, zoom/reflow, motion behavior, and visual focus remain manual review.
Component system (Storybook)
The component lab at /design-system/lab/documents every reusable Astro component in the KISS Design System. Stories cover default states, edge cases (long labels, narrow viewports), and fixture-backed composite layouts.
| Metric | Value |
|---|---|
| Total stories | 31 |
| Component stories | 28 |
| Foundation stories | 3 |
| Storybook accessibility tests | 28 |
See the KISS Design System reference for component documentation, design tokens, and usage guidelines.
Build and validation
The following commands protect the site. Most run in CI on every push to main.
| Command | Purpose |
|---|---|
pnpm typecheck | Astro and TypeScript type checking |
pnpm lint | Biome linting and formatting |
pnpm build | Production Astro build |
pnpm test:e2e | Playwright route, accessibility, and Storybook tests (produces test-results/test-results.json) |
pnpm build:storybook | Storybook static build |
pnpm verify:storybook-isolation | Verify Storybook assets do not leak into production site |
pnpm quality:generate | Generate site-quality.json from current build output and test results |
GitHub Actions on push to main. See .github/workflows/astro.yml.
Measurement limitations
- Lighthouse is a lab measurement. Results vary by environment, device, and network conditions.
- Automated accessibility tools detect only a subset of WCAG criteria. They do not replace manual review.
- Storybook accessibility tests check isolated components, not complete user journeys or page layouts.
- A passing build pipeline does not measure usability, content quality, or design consistency.
- Production Core Web Vitals require real-user monitoring (RUM) data, which this site does not currently collect.
- Static file sizes are raw bytes from the build output. Actual transfer size depends on hosting compression, cache state, and HTTP version.
- Browser-measured transfer sizes require running Playwright network-capture tests against a local preview.
- Storybook bundle weight is measured separately and is not loaded by ordinary blog pages.
- Route-level JavaScript is determined by inspecting generated HTML for <script> references. Dynamic or lazy-loaded scripts are not captured.
- Pagefind assets are present in the deployment but only requested by /search/.
- Partytown worker scripts are present in the deployment but loaded lazily by the Partytown library.
- Inline script bytes are estimated from HTML content. They exclude server-rendered JSON-LD and inline styles.
Methodology
| Measurement group | Type | Source |
|---|---|---|
staticDeployment | static analysis | dist/ directory (Astro-only build) |
routeMeasurements | static analysis | Generated HTML files in dist/ |
componentLab | static analysis | storybook-static/ directory |
stories | static analysis | /home/runner/work/astro.ericcarlisle.com/astro.ericcarlisle.com/storybook-static/index.json |
accessibility | test results | /home/runner/work/astro.ericcarlisle.com/astro.ericcarlisle.com/test-results/test-results.json |
lighthouse | lab measurement | lh-reports/ directory |
isolation | static analysis | dist/ directory |