perf, a11y & SEO: accessible names, meta descriptions, FA subset, asset pipeline#50
Merged
Conversation
Resolves the most widespread Unlighthouse findings across the site: - link-name / button-name (scored 0 on all crawled pages): icon-only social links, mobile-menu toggle, dropdown chevron, and back-to-top button now have aria-labels; decorative icons marked aria-hidden. - meta-description (scored 0 on 65 list/taxonomy/author/pagination pages): these had neither .Description nor .Summary, leaving the tag empty. Add a summary-then-title fallback so every page emits a non-empty description. - unsized-images / image-aspect-ratio: footer CC BY-SA and Netlify badges get explicit width/height matching intrinsic ratio. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Targets the render-blocking and cache-lifetime Unlighthouse findings: - baseof.html: Font Awesome, Prism, alerts, code-copy, and Algolia stylesheets now load via the print-media swap (media=print + onload) instead of blocking first paint. Only the critical fingerprinted Tailwind bundle remains render-blocking. A <noscript> block preserves the blocking links when JS is disabled. - netlify.toml: add Cache-Control for fonts (immutable 1y, they are content-hashed) and images (30d, not fingerprinted). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Replaces the render-blocking ~270 KB Font Awesome CDN webfonts + 30 KB CSS with a self-hosted subset containing only the ~72 glyphs the site actually uses (5.8 KB solid + 2.6 KB brands woff2, 3.1 KB CSS, inlined). - scripts/build-icons.mjs (npm run build:icons): builds the site, scans the output HTML for fa-* classes, resolves them via Font Awesome's metadata (including FA5-era alias names like fa-ticket-alt so legacy classes are not silently dropped), subsets the woff2s, and emits a minimal CSS. Mirrors the build:css committed-artifact model — CI ships the committed files as-is. - baseof.html: drop the FA CDN <link>; inline the subset CSS with fingerprinted, preloaded, font-display:swap @font-face declarations. Regular face is wired conditionally for future-proofing. Verified: all 72 fa-* tokens in the built HTML resolve to real icons (0 silent drops); no CDN font-awesome references remain in output. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Cuts the largest image-delivery offenders flagged by Unlighthouse. - Move logo.png and cc-by-sa.png into assets/images and serve Hugo- processed, fingerprinted WebP at display size: logo 32 KB -> 3.7 KB (80x80), CC badge 101 KB -> 2.7 KB (160px). Both render in the header/ footer on every page, so this saves ~130 KB per page. Explicit width/height retained; the CC badge is lazy-loaded. - schema-site/-article: reference the logo via its resource Permalink (absolute URL) now that it lives in assets, keeping the JSON-LD logo resolvable. - Podcast/author episode cards: request YouTube hqdefault (480x360) instead of maxresdefault (1280x720), ~100 KB -> ~15 KB each, with mqdefault as the onerror fallback. The full-width video facade on single pages keeps maxresdefault for hero quality. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
✅ Deploy Preview for powershellorg ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
…eight The badges carried explicit width/height attrs alongside `w-auto`, but `w-auto` was purged out of the committed Tailwind bundle (it appeared in no other markup), so it was inert and the width attribute squished both badges to full intrinsic width at 24px tall. Remove the static dimensions and let `h-6` set the height with natural width. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The footer badges use w-auto; regenerate the purged bundle so the class is present rather than relying on the img default. Confirms no other introduced classes were missing from the committed bundle. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Deploys ship the committed, purged CSS and subsetted webfonts as-is (bare hugo, not the build:* scripts), so a markup/content change that adds a Tailwind class or fa-* icon silently renders wrong until someone regenerates them — exactly how w-auto slipped through. Add a freshness check to the PR build: regenerate via build:css and build:icons, then fail if assets/css/tailwind.css or assets/css/fontawesome-subset.css differ from what is committed, with a message telling the dev to regenerate and commit. Diffs the generated CSS (deterministic, the source of truth for included classes/icons) rather than the woff2 bytes, which vary across subset-font versions. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- .gitattributes: force LF on the committed generated CSS so the PR guard (regenerated on a Linux runner) can't false-fail on line endings; mark woff2/ttf binary. - ADR 0005: record the build.yml freshness guard as the mitigation for the PurgeCSS silent-removal failure mode, and update the asset section to reflect FontAwesome now shipping as a self-hosted purged subset. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
cf42dd6 to
c77e8ee
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Addresses the most widespread issues from the Unlighthouse audit of the live site, in four focused commits.
Accessibility (
button-name,link-namescored 0 on every crawled page)<i>glyphs markedaria-hidden.SEO (
meta-descriptionscored 0 on 65 list/taxonomy/author/pagination pages)baseof.htmlnow falls back from.Description→ summary → a title-based description, so every page emits a non-empty meta description. Verified 0 published pages missing one.Performance — render-blocking & cache
media="print"swap with a<noscript>fallback; only the critical Tailwind bundle blocks first paint.netlify.toml:Cache-Controlfor fonts (immutable 1y, content-hashed) and images (30d).Performance — Font Awesome subset
scripts/build-icons.mjs(npm run build:icons) scans the built HTML, resolves classes via FA metadata (incl. FA5-era aliases so legacy names aren't silently dropped), and emits a self-hosted subset: ~300 KB CDN webfonts + CSS → ~11.5 KB (5.8 KB solid + 2.6 KB brands woff2, 3.1 KB inlined CSS, fingerprinted + preloaded). Mirrors the committed-artifact model ofbuild:css.Performance — image pipeline
assets/and served as Hugo-processed, display-sized WebP — ~130 KB saved on every page.hqdefaultinstead ofmaxresdefault(~100 KB → ~15 KB each); the full-width video facade keepsmaxresdefaultfor hero quality.Validation
fa-*tokens in the built HTML resolve to real icons (0 silent drops); subsetted woff2s are valid.🤖 Generated with Claude Code