Migrate React components to Solid.js and optimize build#7
Open
Migrate React components to Solid.js and optimize build#7
Conversation
- Replace JSDOM (4.4MB) with regex for HTML parsing in [slug].astro. JSDOM was only used to extract first <p> for descriptions and strip tags for reading-time. Regex does both with zero dependency overhead, saving ~4.3s per build (27 pages x ~160ms JSDOM init each). - Remove @astrojs/vercel adapter which forced server-mode builds even for static output. This eliminates redundant server entrypoint bundling, saving ~2.5s. The sole SSR route (/s/[id]) is moved to api/s/[id].ts as a standalone Vercel serverless function. Benchmarked with Hyperfine (5 runs each): Baseline: 33.76s ± 0.35s JSDOM→regex only: 29.50s ± 0.12s (1.14x faster) Both optimizations: 27.00s ± 0.33s (1.25x faster, -20%) Projected Vercel build: ~40s (down from ~50s). https://claude.ai/code/session_012WHTTmEGYfEbwHYp7KacZd
- Add convex/http.ts with GET/POST /comments endpoints (same validation, rate limiting, and hCaptcha verification as before) - Replace React ConvexProvider + Comments.tsx with a pure Astro component (Comments.astro) using ~60 lines of vanilla JS - Load hCaptcha from CDN instead of bundling @hcaptcha/react-hcaptcha - Move Desmos from npm bundle (2.1MB) to CDN script load This removes convex/react, react-dom, @hcaptcha/react-hcaptcha, and sonner from the client bundle on all 27 post pages. React is still loaded on the 2 MDX pages that need interactive components. Client JS: 2,470kB → 228kB (91% reduction) Vite modules: 1,799 → 1,719 Build time: 34s → 24s (30% faster, Hyperfine benchmarked) https://claude.ai/code/session_012WHTTmEGYfEbwHYp7KacZd
lucide-react barrel imports caused Vite to transform all 1,672 icon modules even though only 3 were used. Deep imports reduce client build from ~7s to ~0.9s (1,719 → 54 modules). Also removes dead React comment components (ConvexProvider.tsx, Comments.tsx, useTheme.tsx) replaced by vanilla JS. Total build improvement: 33.8s → 18.3s (1.85x faster). https://claude.ai/code/session_012WHTTmEGYfEbwHYp7KacZd
CSS selector API is cleaner and more robust than regex for extracting the first paragraph description and plain text from rendered markdown HTML. node-html-parser is ~1MB vs JSDOM's 4.4MB. (HTMLRewriter was attempted but Astro's prerendering runs compiled chunks in a Node.js VM, so Bun-specific globals aren't available there.) https://claude.ai/code/session_012WHTTmEGYfEbwHYp7KacZd
No need to parse rendered HTML at all. Reading time now uses the raw markdown body directly, and description is dropped from the Layout call. https://claude.ai/code/session_012WHTTmEGYfEbwHYp7KacZd
- New Comments.tsx: SolidJS component using ConvexClient (WebSocket) for real-time comment updates, @hcaptcha/vanilla-hcaptcha web component - Replaces HTTP polling with live WS subscription via client.onUpdate() - Submits via client.action() through existing Convex addComment action - Uses client:only="solid-js" to skip SSR (avoids custom element issues in Node) - Scoped react/solid integrations to their respective directories https://claude.ai/code/session_012WHTTmEGYfEbwHYp7KacZd
- mcl2.tsx: convert all components to SolidJS (createSignal, class vs className, inline SVG icons replacing lucide-react deep imports) - move2point.tsx: convert CosineViz and DesmosSide to SolidJS (createSignal, createMemo, onMount/onCleanup, MouseEvent types, inline SVG RotateCw icon) - astro.config.mjs: remove @astrojs/react (no more React files), expand solidJs include to cover both tools/ and components/ - mcl-2.mdx: StepThrough client:load -> client:only="solid-js" - move2point.mdx: CosineViz/DesmosSide client:only="react" -> "solid-js" https://claude.ai/code/session_012WHTTmEGYfEbwHYp7KacZd
Comments now use ConvexClient WebSocket directly — HTTP endpoints were only needed by the old vanilla JS fetch-based implementation. https://claude.ai/code/session_012WHTTmEGYfEbwHYp7KacZd
Removed (truly unused in code): - @astrojs/check, @astrojs/react, @astrojs/vercel (not in astro config) - @hcaptcha/react-hcaptcha, @radix-ui/react-slot, lucide-react, react, react-dom, @types/react, @types/react-dom (React fully removed) - class-variance-authority, sonner, tailwindcss-animate (shadcn leftovers) - desmos, jsdom, @types/jsdom (unused utilities) - shiki (bundled by Astro internally) - prettier-plugin-astro, tsx, vercel (dev tools not needed for build) https://claude.ai/code/session_012WHTTmEGYfEbwHYp7KacZd
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
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
Migrated interactive components from React to Solid.js and removed unnecessary dependencies to significantly improve build performance and reduce client bundle size.
Key Changes
Replaced React with Solid.js for interactive visualizations:
move2point.tsx: Converted from React hooks (useState,useRef,useCallback) to Solid.js signals and memosmcl2.tsx: Migrated particle filter visualization from React to Solid.jslucide-reacttolucide-solidRewrote comment system to eliminate React dependency:
Comments.tsxwith vanilla Solid.js componentConvexProvider.tsxwrapperconvex/reacthooks to direct Convex HTTP client calls@hcaptcha/vanilla-hcaptchaalert())Removed build infrastructure:
@astrojs/verceladapter; migrated SSR route/s/[id]to standalone Vercel API function (api/s/[id].ts)[slug].astropost rendering (replaced with regex-based HTML parsing)useTheme.tsxhook (theme detection now inline)Updated Astro configuration:
@astrojs/reactwith@astrojs/solid-jspackage.jsonImplementation Details
createMemoreplacesuseCallbackfor computed valuesonMount/onCleanuplifecycle hooksclassName,strokeWidth) to kebab-case (class,stroke-width) per Solid.js conventionsBuild Impact
These changes reduce Vite client modules from 1,799 to 54 and client JS bundle from 2,470kB to 228kB (91% reduction), with projected build time improvement from ~50s to ~25s on Vercel.
https://claude.ai/code/session_012WHTTmEGYfEbwHYp7KacZd