perf(nba): load roster once server-side, stop shipping full CSV to client#126
perf(nba): load roster once server-side, stop shipping full CSV to client#126FarhanAliRaza wants to merge 5 commits into
Conversation
Load the roster once at import time instead of re-reading the CSV into per-connection state on every page load, and split the monolithic State into a table-only State and a chart-only StatsState so chart data is never computed or sent to the client while the Table tab is showing. Filtering/aggregation now uses stdlib csv and random plus shared _passes_filters / _average_by helpers, removing the pandas and numpy dependencies entirely.
Greptile SummaryThis PR refactors the NBA template to load the player roster once at import time into a module-level
Confidence Score: 3/5Safe to merge for the performance wins; the pagination count mismatch during search needs attention before it would be considered fully correct. The roster load and chart-data refactoring are well-executed. The main concern is that total_pages derives from the static total_items rather than the length of the filtered player list, so typing a search term and then clicking Last Page navigates to an empty result set. nba/nba/backend/backend.py — the total_pages computed var and the salary sort key for NaN sentinel players. Important Files Changed
|
reflex is a uv workspace, so reflex and its split-out sibling packages (reflex-base, reflex-components-*) must be installed together from the same tree. The old `pip install reflex@git` pulled released sub-packages from PyPI and broke whenever main moved a module between packages. Check out the monorepo to .reflex-src and `uv pip install` it instead, and rename the workflow input from reflex_dep (raw pip spec) to reflex_ref (git ref).
Empty salary/college cells now parse to None (Player fields become Optional) instead of the string "NaN", so sorting, filtering, search and averaging work on real values without special-casing a sentinel. Missing values always sort to the end and render as "—" in the table. Derive total_items from the filtered list, reset offset to 0 on a new search, and floor total_pages at 1, so the page count and navigation can never drift past the actual matches. Also move the Radix theme from rx.App(theme=...) to a RadixThemesPlugin in rxconfig.
Use SQLModel directly with explicit primary-key fields, replace get_fields()/set() with model_fields and setattr, and register RadixThemesPlugin across template rxconfigs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
What
Refactors the
nbatemplate's backend to stop reloading and re-serializingthe entire player roster on every page load.
PLAYERSconstant instead of running
State.load_entrieson every page load andstoring the full list in per-connection state.
full player list lived in state, all ~480 rows of CSV data were serialized
to the client on initial connection. Only the current page (12 rows via
get_current_page) now crosses the wire.Stateinto a table-onlyStateand a chart-onlyStatsState, so chart data is never computed or sent to the client whilethe Table tab is showing.
pandas/numpy(used only for CSV parsing andnp.random.choice)with stdlib
csvandrandom, removing both dependencies._passes_filters/_average_byhelpers.Impact (measured, prod build, 3 profiling passes)