Skip to content

Speed up Pyodide interaction dispatch ~50x (#21

Merged
CSSFrancis merged 1 commit into
mainfrom
perf/pyodide-dispatch
Jun 17, 2026
Merged

Speed up Pyodide interaction dispatch ~50x (#21
CSSFrancis merged 1 commit into
mainfrom
perf/pyodide-dispatch

Conversation

@CSSFrancis

Copy link
Copy Markdown
Owner

The docs ⚡ bridge dispatched every interaction event with pyodide.runPythonAsync(code-string), which parses + compiles a fresh Python code string per event — ~1.2 ms/event in WASM, the dominant per-frame cost of the Pyodide interaction path on a drag (30-60 events/sec). That's why 3D orbit / plane-drag felt sluggish in the docs vs a live Jupyter kernel.

Define a pre-compiled _awi_dispatch(fig_id, data) function once at boot and call its PyProxy directly from the message handler (~0.02 ms/event, ~50x faster, measured end-to-end in Pyodide). The proxy is fetched lazily and cached (robust to boot-step ordering) with a runPythonAsync fallback.

The Python->JS return path was already efficient (a compiled observer closure calling js.window._anywidgetPush), so no change needed there.

All 12 bridge-boot tests pass.

The docs ⚡ bridge dispatched every interaction event with
pyodide.runPythonAsync(code-string), which parses + compiles a fresh Python
code string per event — ~1.2 ms/event in WASM, the dominant per-frame cost
of the Pyodide interaction path on a drag (30-60 events/sec). That's why 3D
orbit / plane-drag felt sluggish in the docs vs a live Jupyter kernel.

Define a pre-compiled `_awi_dispatch(fig_id, data)` function once at boot and
call its PyProxy directly from the message handler (~0.02 ms/event, ~50x
faster, measured end-to-end in Pyodide). The proxy is fetched lazily and
cached (robust to boot-step ordering) with a runPythonAsync fallback.

The Python->JS return path was already efficient (a compiled observer closure
calling js.window._anywidgetPush), so no change needed there.

All 12 bridge-boot tests pass.
@codecov-commenter

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 90.63%. Comparing base (ae47ee8) to head (91a937d).

Additional details and impacted files
@@           Coverage Diff           @@
##             main      #21   +/-   ##
=======================================
  Coverage   90.63%   90.63%           
=======================================
  Files          33       33           
  Lines        2744     2744           
=======================================
  Hits         2487     2487           
  Misses        257      257           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@CSSFrancis CSSFrancis merged commit 364a33f into main Jun 17, 2026
12 checks passed
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.

2 participants