docs: detailed WASM binary size reduction spec
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>
This commit is contained in:
parent
7efd2ab93a
commit
6abda8bfa8
1 changed files with 31 additions and 6 deletions
37
TODO.md
37
TODO.md
|
|
@ -1,20 +1,45 @@
|
|||
# TODO
|
||||
|
||||
## High Priority
|
||||
## High Priority — WASM Binary Size Fix
|
||||
|
||||
- [ ] **Fix WASM binary size** — 1.58 MB gzip exceeds 1 MB limit. Move `buildComponentJS()` and JSON parsing to server-side. WASM should only expose `Render()`. Consider: pre-parsed slots, inline template execution, or TinyGo.
|
||||
- [ ] **Add WASM integration tests** — No `cmd/wasm/main_test.go`. Need JS↔Go round-trip verification.
|
||||
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.go` out of WASM** — Add `//go:build !js` build tag OR delete it from `cmd/wasm/`. The `registerComponents()` JS bridge in `main.go` must also be removed. This removes `encoding/json` and `text/template` from the binary.
|
||||
- [ ] **Move codegen to build-time CLI** — Create `cmd/codegen/main.go` that 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`** — Remove `registerComponents` from the `gohtml` JS object. Only expose `renderToString`. Remove the `encoding/json` and `codegen` imports.
|
||||
|
||||
### Step 2: Remove Pipeline from WASM
|
||||
|
||||
- [ ] **Guard `pipeline.go` with build tag** — Add `//go:build !js` to `pipeline.go`. The `Imprint()` and `CompareVariants()` functions use `go-i18n/reversal` which is heavyweight. These are server-side analysis functions, not needed in browser rendering.
|
||||
- [ ] **Update `cmd/wasm/main.go`** — Ensure no references to `pipeline.go` functions. Currently `renderToString` doesn't use them, so this should be clean.
|
||||
|
||||
### Step 3: Minimise `fmt` Usage
|
||||
|
||||
- [ ] **Replace `fmt.Errorf` in WASM-linked code** — In any source files compiled into WASM (node.go, layout.go, responsive.go, context.go, render.go), replace `fmt.Errorf("...: %w", err)` with `errors.New("...")` or manual string concatenation where wrapping isn't needed. Goal: eliminate `fmt` from 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/` then `gzip -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** — `TestWASMBinarySize` in `cmd/wasm/main_test.go`: build WASM, gzip, assert < 1MB
|
||||
- [ ] **Codegen CLI test** — `cmd/codegen/main_test.go`: pipe JSON stdin → verify JS output matches `GenerateBundle()`
|
||||
- [ ] **renderToString still works** — Existing WASM tests for `renderToString` pass (may need JS runtime like `wasmedge` or build-tag guarded)
|
||||
- [ ] **Existing tests still pass** — `go test ./...` (non-WASM) still passes, pipeline/codegen tests unaffected
|
||||
|
||||
## Medium Priority
|
||||
|
||||
- [ ] **Performance benchmarks** — Add `BenchmarkRender`, `BenchmarkImprint`, `BenchmarkCompareVariants`, `BenchmarkLayout` with varying tree depths.
|
||||
- [ ] **TypeScript type definitions** — Add `.d.ts` generation alongside `GenerateBundle()` for Web Component consumers.
|
||||
- [ ] **Accessibility helpers** — Layout has semantic HTML + ARIA roles but no `aria-label` builder, 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
|
||||
|
||||
- [ ] **Unicode/RTL edge cases** — Test emoji, RTL text, zero-width characters in Text nodes.
|
||||
- [ ] **Deep nesting stress test** — Verify performance with deeply nested Layouts and large `Each[T]` lists.
|
||||
- [ ] **Browser polyfill documentation** — Document closed Shadow DOM support matrix.
|
||||
- [ ] **CSS scoping helper** — Optional utility for responsive variant CSS targeting.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue