Speed up deploy archive creation

Merged
FA
4d ago
+138-9

Split out of #7054 per @masenf's request to land the deploy speedups as separate, individually measured patches. This one only touches archive creation.

Changes

  • Resolve files_to_exclude to (st_dev, st_ino) pairs once, instead of calling Path.samefile() for every walked file and directory against every exclusion (and exists() on each exclusion every time).
  • Store the pre-compressed .gz / .br / .zst frontend sidecars in frontend.zip instead of deflating them a second time. Everything else, including every backend entry, stays ZIP_DEFLATED.
  • Tests cover the stored/deflated choice per archive, exclusion by file identity (hard-link alias), and exclusion through a directory symlink.

Measurement

build.zip_app() on an already-built .web (716 frontend files), 9 iterations × 2 processes, median:

mainthis PR
frontend.zip0.237 s0.184 s (−22%)
backend.zip8.8 ms8.4 ms
frontend.zip size2,746,942 B2,749,455 B (+0.09%)

The whole zip_duration phase of an export on this app is ~0.25 s, so this is a small absolute win; it is also the simplest patch in the set.

Measurement setup

Five-page app from the blank template (Radix Themes + Tailwind v4 plugins), Linux x86_64, 4 vCPU, Python 3.14, Node 22.22, npm 10.9, bun 1.4.2. Each run is a fresh interpreter calling reflex.utils.export.export() the same way reflex export does; durations are the phase timings the export already reports to telemetry (compile includes the dependency install). Medians of 3 runs unless noted. Vite dominates every export (~6.5 s); these numbers isolate the part this PR touches.

Type of change

  • Performance improvement (non-breaking)

Checklist

  • Tests added for the change; the full tests/units suite passes locally except the 14 reflex_bench/drivers/test_browser.py cases that need a Playwright browser launch, which fail identically on untouched main in this sandbox
  • ruff check, ruff format --check, codespell, and pyright reflex tests pass locally
  • News fragment added for every package touched

https://claude.ai/code/session_018nWB9r2HcC5tkT72UxWgGj


Generated by Claude Code