Avoid full payload reships for restyles and unchanged columns#189
Avoid full payload reships for restyles and unchanged columns#189Alek99 wants to merge 1 commit into
Conversation
Merging this PR will degrade performance by 34.47%
|
| Benchmark | BASE |
HEAD |
Efficiency | |
|---|---|---|---|---|
| ❌ | test_animation_keyed_payload_100k |
5.4 ms | 13 ms | -58.41% |
| ❌ | test_animation_plain_payload_100k |
3.3 ms | 7.1 ms | -53.29% |
| ❌ | test_first_payload_scatter_continuous_channels |
8.6 ms | 16.2 ms | -46.76% |
| ❌ | test_first_payload_scatter_medium |
5.6 ms | 9.4 ms | -40.59% |
| ❌ | test_build_scatter_medium_raw |
5.6 ms | 9.4 ms | -40.28% |
| ❌ | test_build_scatter_medium_pyplot |
6.4 ms | 10.2 ms | -37.23% |
| ❌ | test_first_payload_scatter_small |
1.4 ms | 1.8 ms | -21.59% |
| ❌ | test_build_line_small_raw |
1.5 ms | 1.9 ms | -20.49% |
| ❌ | test_build_styled_panel_raw |
2.3 ms | 2.9 ms | -20.08% |
| ❌ | test_first_payload_scatter_categorical_color |
17.3 ms | 21.6 ms | -19.76% |
| ❌ | test_first_payload_heatmap_core_2d |
1.6 ms | 2 ms | -18.63% |
| ❌ | test_build_line_small_pyplot |
2 ms | 2.4 ms | -16.3% |
| 🆕 | test_restyle_full_split_payload_comparator_200k |
N/A | 11.4 ms | N/A |
| 🆕 | test_restyle_json_only_200k |
N/A | 262.7 µs | N/A |
Tip
Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.
Comparing agent/restyle-without-reship (8143417) with main (2a7d898)
Footnotes
-
1 benchmark was skipped, so the baseline result was used instead. If it was deleted from the codebase, click here and archive it to remove it from the performance reports. ↩
Greptile SummaryThis PR adds lightweight restyling and reuse across the payload and rendering paths. The main changes are:
Confidence Score: 4/5Concurrent restyles and payload builds can leave stale payloads cached for new subscribers. Payload construction is serialized with An in-flight pre-restyle build can repopulate the cache after invalidation in python/reflex-xy/reflex_xy/registry.py.
What T-Rex did
Important Files Changed
Reviews (1): Last reviewed commit: "Avoid full payload reships for restyles" | Re-trigger Greptile |
| message = entry.figure.restyle_message(trace, style, **kwargs) | ||
| # Same full-payload version (existing clients need not advance their | ||
| # message guard), but a later subscriber must build a spec containing | ||
| # the new constants rather than reuse a pre-restyle cached spec. | ||
| with self._mutex: | ||
| entry.payload_cache.clear() |
There was a problem hiding this comment.
Restyle Can Restore Stale Payloads
restyle_message() mutates the figure and clears its cache without entry.lock, while _cached_payload() builds and stores payloads under that lock. If a subscription is encoding during a restyle, the in-flight build can insert the old appearance after this clear under the unchanged (version, bucket) key, so later subscribers receive stale styles. The mutation and cache invalidation must be serialized with payload construction.
Artifacts
Repro: deterministic stale payload cache race harness
- Contains supporting evidence from the run (text/x-python; charset=utf-8).
Repro: successful execution showing stale pre-restyle constants returned to a later subscriber
- Keeps the command output available without making the summary code-heavy.
Summary
Chart,FigureWidget, and ReflexMutable decimated tiers, density textures, retained samples, and drill subsets remain generation-local. Sparse payload resolution is transactional; malformed or missing deltas preserve the last good manifest. Cache state is mount-addressed, cleared on unsubscribe/disconnect, and released on trace teardown or WebGL context loss.
Verification
pytest -q: 2227 passed, 66 skipped in 85.01spytest -q benchmarks/test_codspeed_restyle.py --codspeed: 2 passedruff check .: passedruff format --check .: 343 files already formattedtsc -p js/tsconfig.json --noEmit: passednode js/build.mjs --check: shipped bundles freshgit diff --check: passedThe browser probes verify that direct restyles preserve payload and WebGL buffer identity, density restyles preserve textures/sample buffers, invalid messages fail closed, sparse manifests reconstruct transactionally, direct-tier buffers are reused with balanced references, mutable tiers are excluded, and context teardown clears cached handles.
Local 200k-point benchmark
That is an 897.1× median control-plane speedup for the JSON restyle in this local run, while eliminating all 1.6 MB of binary retransmission for style-only updates.
Closes #163