# SPEED — zellij (sl0p fork) _Read this BEFORE running anything slow._ The single biggest trap in this repo: **`cargo build --release` takes ~3 minutes for a one-line change.** `[profile.release]` sets `lto = true` + `codegen-units = 1`, so every rebuild redoes whole-program optimization on one core. That is correct for shipping and absurd for iteration. Use the `fastdev` profile instead. Same `opt-level = 3`, no LTO, 16 codegen units, incremental cache kept. --- ## Commands ```bash # cheap gate — ALWAYS before test/build cargo check -p zellij-server # ~7s incremental # narrow test — DEFAULT RUNG cargo test -p zellij-server --lib ui::pane_boundaries_frame # ~5s incremental cargo test -p zellij-utils --lib gap_and_padding_tests # ~5s incremental # deployable binary for looking at it in a terminal cargo build --profile fastdev -p zellij # ~3s incremental -> target/fastdev/zellij # real release (shipping / benchmarking only) cargo build --release -p zellij # ~3min <-- BACKGROUND ONLY # full suite — BACKGROUND ONLY, once, at the gate bgrun run suite -- cargo test -p zellij-server --lib bgrun check suite ``` ## Measured timings | command | time | notes | |---|---|---| | `cargo build --profile fastdev -p zellij` (incremental) | **2.8s** | zellij-server edit + relink | | `cargo build --profile fastdev -p zellij` (cold) | 2m29s | one-time, per profile | | `cargo build --release -p zellij` (incremental) | **~3min** | LTO + codegen-units=1. Avoid in the loop. | | `cargo test -p zellij-server --lib ` (incremental) | 4.8s | compile dominates; run is ~0.0s | | `cargo test -p zellij-server --lib` (full) | ~7s run | after compile; **green** | | `cargo test -p zellij-utils --lib` (full) | ~0.3s run | **green** | ## Deploy loop (what we actually do) ```bash cargo build --profile fastdev -p zellij \ && rm -f ~/bin/zellij \ && cp target/fastdev/zellij ~/bin/zellij # rm first: "Text file busy" if running ``` Then start a **new session** — a running server keeps its old inode. Config-only changes (`gap`/`padding`/`title_alignment`) hot-reload; renderer changes do not. ## TEST BASELINE: GREEN Both crates pass clean. **Any failure you see is yours** — this is no longer a tree where failures are background noise. ``` cargo test -p zellij-server -p zellij-utils --no-fail-fast # zellij-server: 1475 passed, 0 failed # zellij-utils: 443 passed, 0 failed ``` Historical note: this tree used to carry 30 failures in `zellij-server` and 5 in `zellij-utils`, from the first sl0p commit (aa51848d) onward. They were never real bugs — `aa51848d` changed the scroll indicator and the frame-title rendering but did not refresh the `insta` snapshots. Fixed in 5f2c28ab. Two traps that hid this for so long, worth remembering: - **cargo stops at the first failing test binary.** The 30 `zellij-server` failures meant `zellij-utils` never ran at all, so its 5 failures were invisible. Use `--no-fail-fast` when you want the true picture across crates. - **insta aborts a test at its first snapshot mismatch.** Tests that assert several snapshots only reveal the next one once the previous is fixed, so regenerating takes several passes. Loop until `.snap.new` count reaches 0. Regenerating snapshots (no `cargo-insta` installed here): ```bash find . -name '*.snap.new' -delete INSTA_UPDATE=new cargo test -p zellij-server --lib # REVIEW the .snap.new diffs before accepting -- they are the only thing # standing between an intended UI change and a silent regression for f in $(find . -name '*.snap.new'); do mv "$f" "${f%.new}"; done ``` ## SLOW TRAPS - `cargo build --release` in the inner loop — 60x slower than `fastdev` for no benefit. - `cargo clean` — forfeits the incremental cache; never without evidence of a stale artifact. - `cargo check --workspace --all-targets` — fails on missing **debug-profile** wasm plugin assets (`target/wasm32-wasip1/debug/*.wasm`). Not a real error. Use `-p --all-targets`. - The gold linker "works" but rustc warns it is deprecated with known Rust bugs. `lld` is NOT installed (only `rust-lld` inside the toolchain, which needs nightly flags to use). Not worth it — dropping LTO already removed the dominant cost. ## Fork context Branch `sl0p/base`. `main` tracks upstream and is left clean. Custom options live in `ui { pane_frames { title_alignment, gap, padding } }`.