5-step plan: remove registerComponents() from WASM (saves encoding/json + text/template), guard pipeline.go with build tag (saves go-i18n/reversal), minimise fmt usage, build-time codegen CLI, size verification tests. Target: 1.58MB → <1MB gzip. Co-Authored-By: Virgil <virgil@lethean.io>
3.5 KiB
3.5 KiB
TODO
High Priority — WASM Binary Size Fix
Current: 6.04 MB raw / 1.58 MB gzip. Target: < 1 MB gzip (Makefile gate: WASM_GZ_LIMIT 1048576).
Root cause: registerComponents() pulls in encoding/json (~200KB gz), text/template (~125KB gz), and fmt (~50KB gz). Plus pipeline.go links go-i18n/reversal (~250KB gz). These are heavyweight imports for code that doesn't need to run client-side.
Step 1: Remove registerComponents() from WASM
- Move
cmd/wasm/register.goout of WASM — Add//go:build !jsbuild tag OR delete it fromcmd/wasm/. TheregisterComponents()JS bridge inmain.gomust also be removed. This removesencoding/jsonandtext/templatefrom the binary. - Move codegen to build-time CLI — Create
cmd/codegen/main.gothat reads slot config from stdin (JSON) and writes generated JS to stdout. This replaces the WASM-based registration. Usage:echo '{"H":"nav-bar","C":"main-content"}' | go run ./cmd/codegen/ > components.js. Consumers pre-generate during build. - Update
cmd/wasm/main.go— RemoveregisterComponentsfrom thegohtmlJS object. Only exposerenderToString. Remove theencoding/jsonandcodegenimports.
Step 2: Remove Pipeline from WASM
- Guard
pipeline.gowith build tag — Add//go:build !jstopipeline.go. TheImprint()andCompareVariants()functions usego-i18n/reversalwhich is heavyweight. These are server-side analysis functions, not needed in browser rendering. - Update
cmd/wasm/main.go— Ensure no references topipeline.gofunctions. CurrentlyrenderToStringdoesn't use them, so this should be clean.
Step 3: Minimise fmt Usage
- Replace
fmt.Errorfin WASM-linked code — In any source files compiled into WASM (node.go, layout.go, responsive.go, context.go, render.go), replacefmt.Errorf("...: %w", err)witherrors.New("...")or manual string concatenation where wrapping isn't needed. Goal: eliminatefmtfrom the WASM import graph entirely if possible.
Step 4: Verify Size
- Build and measure — Run
GOOS=js GOARCH=wasm go build -o gohtml.wasm ./cmd/wasm/thengzip -9 -c gohtml.wasm | wc -c. Must be < 1,048,576 bytes. Update Makefile if the gate passes. - Document the server/client split — Update CLAUDE.md with the new architecture: WASM =
renderToString()only, codegen = build-time CLI.
Step 5: Tests
- WASM build gate test —
TestWASMBinarySizeincmd/wasm/main_test.go: build WASM, gzip, assert < 1MB - Codegen CLI test —
cmd/codegen/main_test.go: pipe JSON stdin → verify JS output matchesGenerateBundle() - renderToString still works — Existing WASM tests for
renderToStringpass (may need JS runtime likewasmedgeor build-tag guarded) - Existing tests still pass —
go test ./...(non-WASM) still passes, pipeline/codegen tests unaffected
Medium Priority
- TypeScript type definitions — Add
.d.tsgeneration alongsideGenerateBundle()for Web Component consumers. - Accessibility helpers — Layout has semantic HTML + ARIA roles but no
aria-labelbuilder, alt text helpers, or focus management nodes. - Layout variant validation —
NewLayout("XYZ")silently produces empty output. Add warning or error for invalid slot characters.
Low Priority
- Browser polyfill documentation — Document closed Shadow DOM support matrix.
- CSS scoping helper — Optional utility for responsive variant CSS targeting.