Skip to content

perf(dev): bound light webpack runtime - #587

Draft
beruro wants to merge 3 commits into
developfrom
junyu/light-dev-webpack-config
Draft

perf(dev): bound light webpack runtime#587
beruro wants to merge 3 commits into
developfrom
junyu/light-dev-webpack-config

Conversation

@beruro

@beruro beruro commented Jul 30, 2026

Copy link
Copy Markdown
Collaborator

Problem

Light development inherited webpack's persistent filesystem cache even though the process is intentionally disposable. On the current develop baseline that cache wrote about 1.57 GiB under node_modules/.cache/webpack, while startup and repeated rebuilds remained slow. A memory-only cache removes the disk write and improves latency, but without a process limit it reached about 3.10 GiB RSS across ten rebuilds on the same bundle, so cache selection alone does not provide a reliable runtime bound.

Solution

  • Disable the webpack-dev-server browser client, HMR, and live reload only in light development mode.
  • Use a memory cache retaining one unused generation only in light mode; ordinary development keeps dev-11 filesystem caching and production keeps its isolated prod-11 / prod-fast-11 caches.
  • Give only the light webpack frontend child a default 1792 MiB V8 old-space limit. Existing NODE_OPTIONS are preserved, and an explicit user --max-old-space-size / --max_old_space_size setting wins.
  • Cover light/ordinary/production cache isolation plus default, preserved, overridden, and non-light child environments with Node regression tests.

Potential risks

  • The current-head lifecycle run observed a higher startup/early-rebuild RSS peak than the filesystem-cache baseline: about 2.03 GiB versus 1.72 GiB (approximately +18%). The limit prevents the memory-cache path from continuing to the 3.10 GiB seen without it, and the 30-second steady median was slightly lower (1.17 GiB versus 1.23 GiB), but this is a latency/disk/runtime-bound tradeoff rather than an across-the-board RSS reduction.
  • Users who explicitly provide their own Node heap limit keep control; a larger override can remove the measured bound, while an unusually small override can make webpack fail to compile.
  • Results are comparative measurements from one macOS machine and may vary with filesystem, GC timing, and memory pressure. They are not universal memory thresholds.
  • Rollback is a normal revert of the three PR commits. No application data, persistence format, dependency, public API, or production bundle behavior changes.

Verification

Configuration and correctness checks on published head 888e4d590, rebased onto develop at 9a2d6f6cf:

  • node --test scripts/dev/tauri-dev-processes.test.cjs scripts/dev/webpack-config-light.test.cjs — passed, 18/18 tests.
  • node --check scripts/dev/tauri.js, node --check scripts/dev/tauri-dev-processes.cjs, and node --check webpack.config.js — passed.
  • pnpm exec tsc --noEmit — passed.
  • pnpm exec prettier --check scripts/dev/tauri.js scripts/dev/tauri-dev-processes.cjs scripts/dev/tauri-dev-processes.test.cjs scripts/dev/webpack-config-light.test.cjs webpack.config.js — passed.
  • git diff --check plus scope/secrets/personal-path/debug-output inspection — passed; the final diff is limited to five light-dev configuration, launcher, and regression-test files.
  • Repository ESLint ignores these Node/CJS configuration scripts. A forced eslint --no-ignore was attempted but is not a valid project gate because the repository ESLint config does not declare Node globals for these ignored files; Node tests, syntax checks, Prettier, and the commit hook are the applicable checks.

Performance lifecycle method:

  • Installed the same lockfile independently in current-base and PR worktrees with pnpm install --frozen-lockfile.
  • Cleared only each worktree's webpack build cache, ran one prewarm process, then a separate lifecycle process.
  • Waited for WEBPACK_STATUS:done_initial, requested /main.js, sampled the webpack PID RSS every 250 ms, touched src/index.tsx ten times, waited for a successful WEBPACK_STATUS:done after each touch, sampled a 30-second steady window, inspected cache bytes, and sent SIGTERM.
  • Current develop: lifecycle ready in 39.5 s; ten rebuilds in 3.2–8.8 s; observed rebuild peak 1.72 GiB; steady median 1.23 GiB; filesystem cache 1.57 GiB.
  • PR with the launcher's 1792 MiB limit: lifecycle ready in 25.2 s; ten rebuilds in 2.25–2.99 s; observed rebuild peak 2.03 GiB; steady median 1.17 GiB; no filesystem cache directory.
  • Both final runs completed 10/10 rebuilds without WEBPACK_STATUS:error and exited successfully after SIGTERM.
  • The unbounded memory-cache candidate reached 3.10 GiB RSS. A maxGenerations: 0 candidate was rejected after failing to complete the lifecycle within ten minutes and its experimental change was fully reverted.

Performance verdict: PASS for bounded light-process growth, disk-cache elimination, faster startup/rebuilds, and clean lifecycle teardown, with the measured +18% early peak versus the filesystem-cache baseline explicitly accepted as the remaining tradeoff.

GitHub CI is running on the published head. The PR remains Draft until the new frontend, Rust, and attribution checks pass.

@beruro
beruro force-pushed the junyu/light-dev-webpack-config branch from bdeda38 to 459275b Compare July 30, 2026 15:10
@beruro
beruro marked this pull request as draft August 10, 2026 03:35
@beruro
beruro force-pushed the junyu/light-dev-webpack-config branch from df990b2 to 350ff60 Compare August 10, 2026 04:04
@beruro
beruro force-pushed the junyu/light-dev-webpack-config branch from 3681d62 to 888e4d5 Compare August 10, 2026 05:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant