Skip to content

Site optimization 2026: delivery, images, SEO, agents, a11y, CI - #56

Merged
tylerkstevens merged 12 commits into
mainfrom
perf/optimization-2026
Oct 14, 2026
Merged

tylerkstevens merged 12 commits into
mainfrom
perf/optimization-2026

Conversation

@tylerkstevens

Copy link
Copy Markdown
Collaborator

Full plan + guardrails: docs/optimization-plan.md. Behaviour, delivery, and metadata only. No visual redesign.

What's in it

Delivery & caching (P0)

  • next.config.ts headers(): year-long immutable caching on public assets + hashed chunks (removes Next's max-age=0 on public/), baseline security headers on every response. HTML/ISR caching untouched.
  • Enforced CSP (dev-only unsafe-eval gated out of prod).

CI (P0)

  • .github/workflows/ci.yml: lint, tests, production build, and a Lighthouse budget (lighthouserc.json) on PRs.

Images (P1)

  • scripts/optimize-art.mjs now covers community heroes, root hero art and team headshots, and re-encodes existing WebP in place; newsroom quality 78->74; community capped at 1600px. public/ 8.2 MB -> 6.1 MB.
  • Team headshots -> WebP; OG cards palette-quantized (~90 KB -> ~40 KB each).

SEO (P1)

  • Site-wide JSON-LD @graph (NGO + WebSite, @id-linked), BreadcrumbList on interior pages, ItemList on /projects, Person list on /mission, richer NewsArticle; manifest.ts; branded not-found/error; viewport/themeColor; fixed a nested <main>.

Agent surfaces (P1)

  • Accept: text/markdown content negotiation + Link rel="llms" (middleware.ts), /.well-known/{security,ai}.txt, RSS dc:creator + content:encoded.
  • @next/bundle-analyzer + npm run analyze.

A11y / hygiene

  • Fixed every contrast + heading-order issue the Lighthouse budget caught; skip-to-content link; pruned dead primitives; docs updated.

Verification

Lighthouse on /, /projects, /newsroom, /contact: Performance 99-100, Accessibility 100, SEO 100; Best Practices 100 except / at 78 (the Vimeo embed's third-party cookie, external). Lint clean, 51/51 tests pass, production build green.

Deploy notes (out of repo)

Reverse proxy should serve brotli + HTTP/2/3, preserve the app's Cache-Control/Vary, and mount a persistent volume at .next/cache/images. A www -> apex 308 belongs at the proxy.

Deep plan for delivery/caching headers, image pipeline, JS/CWV,
SEO/schema depth, agent (AEO) surfaces, security hardening, CI gates,
a11y, and asset hygiene. Baseline + targets included.
- next.config: headers() with year-long immutable caching for static
  assets and hashed chunks; baseline security headers on all responses;
  explicit compress: true. HTML keeps Next ISR defaults.
- CI workflow: lint, test, production build, Lighthouse budget on PRs.
- lighthouserc.json + npm run lhci (dev dep @lhci/cli).
- optimize-art: cover community heroes, team headshots, and root hero
  art; re-encode existing WebP in place; cap community at 1600px.
- optimize-images: newsroom quality 78 -> 74.
- team headshots converted .jpg -> .webp (refs updated).
- raw <img> card logos get loading=lazy + decoding=async.
- agentSeo: site-wide @graph (NGO + WebSite, @id-linked), breadcrumb/
  ItemList/team builders; richer NewsArticle (articleSection, project,
  @id, publisher @id, image always).
- layout: emit site graph, add viewport/themeColor + robots directives,
  advertise text/markdown alternate.
- BreadcrumbList wired across all interior pages; ItemList on /projects;
  Person list on /mission.
- Add app/manifest.ts, branded app/not-found.tsx and app/error.tsx.
- Fix nested <main> inside layout <main> on /projects.
- robots: add host.
- middleware: Accept: text/markdown returns the markdown twin
  (/ -> /llms.txt, /newsroom/<slug> -> raw post); Link rel=llms header.
- public/.well-known/security.txt and ai.txt.
- rss.xml: dc:creator + content:encoded (full post body).
- @next/bundle-analyzer dev dep + npm run analyze (.next/analyze).
- Content-Security-Policy-Report-Only covering Next inline bootstrap,
  Vimeo/YouTube frames, Substack embed, Formspree, Umami.
- Add a skip-to-content link and #main-content target.
- Remove unused primitives (SectionHeader, ExternalLink, ASCIIArt,
  Timeline); update README/CLAUDE trees.
- README: delivery/caching/proxy + agent-surface notes.
- optimization plan status; ui-work-log Round 18; CLAUDE delivery section.
- Footer: gray-400/gray-700 -> gray-500/400; column headings h3 -> h2.
- Sweep text-gray-400 dark:text-gray-600 -> gray-500/400 (light contrast).
- PostCard/newsroom/grants timestamps, StackSubNav index, projects labels.
- NewsroomIndex: sr-only h2 so h1 -> h2 -> h3 order holds.
- Drop upgrade-insecure-requests from the report-only CSP (ignored there,
  logged console errors); vimeo dnt=1.
- lighthouserc: allow the Vimeo third-party-cookie audit; ignore .lighthouseci.

LHCI: perf/a11y/seo 100 on /, /projects, /newsroom, /contact.
Clean report-only pass on all audited pages, so ship the policy for real.
LHCI green: perf 99-100, a11y/seo 100; best-practices 100 except / (78,
Vimeo third-party cookie).
Production bundle does not eval, so prod CSP stays tight; dev no longer
logs a CSP EvalError.
@tylerkstevens
tylerkstevens merged commit bb9d30a into main Oct 14, 2026
1 check failed
tylerkstevens added a commit that referenced this pull request Oct 14, 2026
- ui-work-log: add #56 to the branch/PR table as merged; mark Round 18 merged
- session-context: date bump, TL;DR points at the optimization round, PR history
- optimization-plan: status now merged; list remaining P2/proxy work
- CLAUDE.md: fix stale Vercel hosting line; document manifest/.well-known/middleware,
  skip link, JSON-LD graph in the route map
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant