perf: scope KaTeX/fonts/middleware/JSON-LD, fix stale caching + O(N^2) build#21
Merged
Conversation
…) build Ten independent load-time and build-time fixes, each verified via a clean production build + zero-error lint pass: - Split Formula/TeX out of KnowledgeLayout.jsx into KatexFormula.jsx so the katex JS library (76KB gzip) and its CSS only load on the 39/68 knowledge pages that actually render maths, not all 68. Switched katex.min.css to the -swap variant (font-display:swap) to remove a FOIT risk on those pages. - lib/fonts.js: stop eagerly preloading the Bitcount local font (~35KB) everywhere except where it's actually above the fold; display:swap already prevents FOIT elsewhere. - middleware.js: tighten the matcher to skip static file extensions so every font/image/css request doesn't take an Edge Middleware hop. - Move homepage-only JSON-LD (breadcrumb, projects, credentials) out of the global _document.jsx into pages/index.jsx — was shipping on all ~300 pages. - Remove dead dns-prefetch hints and images.remotePatterns entries for hosts no longer used now that logos are self-hosted. - public/sw.js: switch /images/* from cache-first to stale-while-revalidate — filenames aren't content-hashed, so cache-first could serve a replaced image forever to returning visitors. - Delete two unreferenced images (heroSection1.png, 404.png — 2.3MB, zero references anywhere in the repo). - Fix a CSS bug where h1's font-family targeted a string that doesn't match the compiled @font-face name, silently falling back to system monospace on ~70 page titles site-wide. - lib/posts.js: split parsePost into a cheap metadata-only parse (used by getAllPosts) and the full remark pipeline (used per-page) — turns /blog/[slug]'s O(N^2) build-time parsing into O(N). Measured 11.3s -> 3.4s for the current 18 posts. Deliberately NOT done: splitting both locale JSON files apart (the real gzip cost is ~28KB one-time per session, not per-page, and a correct fix needs getStaticProps rolled out across ~300 pages) and splitting DM Sans/Playfair's italic preload (next/font's preload option is all-or-nothing per call, so a safe split would need a second font-family and CSS rules to route italic text to it — too much surface for a zero-test-coverage site). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
CI's format check was failing on v5 itself (unrelated to the perf changes in this branch) — fixing here so this PR's CI is green. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
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.
Summary
Ten independent load-time / build-time fixes from a full performance audit. Each verified via clean
npm run build+npm run lint(0 errors).Real load-time wins:
/knowledgepages that actually render maths (was leaking a 76KB gzip chunk into all 68). Also switched tokatex-swap.min.cssto remove a FOIT risk.middleware.jsmatcher tightened to skip static file extensions — every font/image/css request no longer takes an Edge Middleware hop._document.jsxintopages/index.jsx— was shipping on all ~300 pages.Correctness/hygiene fixes found along the way:
sw.js:/images/*switched from cache-first to stale-while-revalidate (filenames aren't content-hashed, so a replaced image could stay stale forever for returning visitors).h1'sfont-familydidn't match the compiled@font-facename — ~70 page titles were silently falling back to system monospace.dns-prefetchhints +remotePatternsentries for hosts no longer used (logos are self-hosted now).lib/posts.js: split metadata-only parsing from full-content parsing, turning/blog/[slug]'s O(N²) build-time markdown parsing into O(N). Measured 11.3s → 3.4s for the current 18 posts (build-time only, not visitor-facing).Deliberately NOT done (assessed and scoped back after finding real risk):
getStaticPropsrolled out across ~300 pages.next/font'spreloadoption is all-or-nothing per call; a safe split needs a second font-family + CSS routing rules, too much surface for a site with zero test coverage.Test plan
npm run lint— 0 errors, 194 pre-existing warnings (unchanged)npm run build— succeeds, same pre-existing warnings (unrelated@vercel/kvmodule notice)/knowledge/kalman-filter) and one without (e.g./knowledge/topic-modelling), locale switch, dark/light mode, and the CLI easter egg (curlthe site or check/api/curlstill triggers for CLI user agents).🤖 Generated with Claude Code