ENG-9148: feat(compiler): incremental compile cache & warm hot-reload daemon (REFLEX_COMPILE_CACHE)

FA
1d ago
+13805-359

An experimental, flag-gated frontend compile pipeline that recompiles only the pages whose source actually changed and reuses the rest. Off by default; enabled by REFLEX_COMPILE_CACHE. The compile path is completely unchanged when the flag is unset.

What it does

On-disk incremental cache (disk_cache.py + page_cache.py)

A fresh compile process reuses the previous build already on disk in .web and recompiles only the pages whose source changed. Each page is invalidated by a precise dependency set rather than a global timestamp:

  • the page's first-party Python import closure,
  • files read while the page is evaluated (markdown/data, including runtime importlib imports and data read at import time),
  • the component modules in its rendered tree, and
  • the fine-grained state files it references.

Pages are keyed by the content hashes of that set plus a small global epoch — Reflex version, rxconfig/lockfiles, and the app entrypoint's config-only modules (theme, app-wraps, stylesheets, head components, plus config the app imports dynamically at load time). A change to a genuinely-global input forces a full recompile; per-file edits invalidate only the pages that depend on them. Any unsafe condition falls back to a full compile, so a cache miss is never a correctness risk.

Warm fork-per-compile hot-reload daemon (compile_daemon.py)

reflex run dev imports the app once, then compiles each edit in an isolated child — forking on POSIX so third-party imports stay warm (falling back to a fresh process elsewhere). Combined with the disk cache, a hot reload skips the cold reimport and rebuilds only what changed.

Supporting changes required for safe page reuse: deterministic compile-time ref-name generation, own-before-mutate page-metadata injection, and mirroring memo output paths to their Python source modules.

All Submissions:

  • Have you followed the guidelines stated in CONTRIBUTING.md file?
  • Have you checked to ensure there aren't any other open Pull Requests for the desired changed?

Type of change

  • New feature (non-breaking change which adds functionality)

New Feature Submission:

  • Does your submission pass the tests?
  • Have you linted your code locally prior to submission?

Changes To Core Features:

  • Have you added an explanation of what your changes do and why you'd like us to include them?
  • Have you written new tests for your core changes, as applicable?
  • Have you successfully ran tests with your changes locally?