wasm-optimization
Auto-activates when discussing WASM performance, binary size, or optimization. Guides through release build optimization and performance analysis.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Auto-activates when discussing WASM performance, binary size, or optimization. Guides through release build optimization and performance analysis.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
| name | wasm-optimization |
| description | Auto-activates when discussing WASM performance, binary size, or optimization. Guides through release build optimization and performance analysis. |
This skill activates when discussing WebAssembly performance optimization for the Apple1JS CPU emulator.
Optimization goal: SPEED, not size. The project deliberately chose
opt-level = 3+-O3wasm-opt to reach ~14× JS raw throughput, accepting a larger binary (~155 KB release) in the trade. Older docs that say "<100KB" / "90KB" /opt-level = "z"describe an abandoned size-first strategy — do not restore it without explicit user approval (it reverses the perf win). Seedocs/active/wasm-performance.md.
Build with release profile (or just yarn wasm:build:release):
cd wasm-cpu && wasm-pack build --release --target web --out-dir ../src/wasm
yarn dev already builds --release; yarn dev:debug-wasm keeps the slow --dev build for
Rust debugging only. Never benchmark a --dev build — debug Rust/WASM is ~10× slower.
Current Cargo.toml settings (wasm-cpu/Cargo.toml):
[profile.release]
opt-level = 3 # Optimize for SPEED (the emulation hot loop)
lto = true # Link-time optimization
codegen-units = 1 # Better optimization
strip = true # Strip symbols
# wasm-pack runs wasm-opt AFTER wasm-bindgen. The key MUST be profile-scoped or it is
# silently ignored; bare `-O` fails on this module's bulk-memory / non-trapping ops.
[package.metadata.wasm-pack.profile.release]
wasm-opt = ['-O3', '--enable-bulk-memory', '--enable-nontrapping-float-to-int']
Verify binary size:
ls -lh src/wasm/apple1_cpu_wasm_bg.wasm
Expected: ~155 KB release (speed-first). A drop toward ~90 KB likely means someone
reverted to opt-level = "z" and gave back the speed.
Avoid allocations in hot paths:
Inline critical functions:
#[inline(always)]
fn read_byte(&self, addr: u16) -> u8 { ... }
Use lookup tables:
Minimize JS↔WASM boundary crossings:
The real speedup is only measurable headless (no Clock, no React) — the benchmark is gated
behind BENCH=1 so it never runs in normal CI:
yarn wasm:build:release
BENCH=1 npx vitest run src/core/cpu-engines/__tests__/wasm-benchmark.vitest.test.ts
Do NOT judge speed from in-app IPS. The
Clockthrottles both engines to ~1MHz, so both read ~331K IPS regardless of engine — comparing them shows no difference by design. In-app, the real signal is Host CPU (hostMillisPerSecond): host wall-clock ms per emulated second, displayed as load% + headroom in the Performance Metrics panel. Lower = better.
Key metrics:
--release (and yarn dev ships release).[package.metadata.wasm-pack.profile.release],
and must enable --enable-bulk-memory --enable-nontrapping-float-to-int or the build fails.$D010–$D013 should cross).// GOOD: Direct memory access
let byte = self.memory[addr as usize];
// BAD: Function call overhead in tight loop
let byte = self.read_memory(addr);
// GOOD: Pre-computed lookup
const FLAG_TABLE: [u8; 256] = [...];
self.flags = FLAG_TABLE[result as usize];
// BAD: Runtime computation
self.flags = if result == 0 { Z_FLAG } else { 0 } | if result & 0x80 != 0 { N_FLAG } else { 0 };
| Setting | Size Impact | Speed Impact |
|---|---|---|
opt-level = "z" | Smallest | Slower |
opt-level = "s" | Small | Medium |
opt-level = 3 | Largest | Fastest |
lto = true | Smaller | Faster |
codegen-units = 1 | Smaller | Faster |
For Apple1JS, prefer opt-level = 3 + -O3 wasm-opt. The emulator chases raw throughput (and the
headroom to run faster-than-1MHz "turbo" modes later), so speed wins over the ~65 KB of binary that
opt-level = "z" would save. Only revisit size-first if the user explicitly prioritizes download
size over speed.