Skip to content

perf: improve large-sequence rendering - #12

Merged
bughht merged 1 commit into
bughht:mainfrom
AssociatedPrimeIdeal:perf/block-position-prefix
Jul 11, 2026
Merged

perf: improve large-sequence rendering#12
bughht merged 1 commit into
bughht:mainfrom
AssociatedPrimeIdeal:perf/block-position-prefix

Conversation

@AssociatedPrimeIdeal

Copy link
Copy Markdown
Contributor

Summary

Fixes large-sequence loading and interaction bottlenecks.

Performance Issues Fixed

  1. Quadratic minimap block-position construction (seqEditorProvider.ts)

    • Replaced the per-block prefix rescan with one running cumulative duration.
    • Changes block-position preparation from O(n^2) to O(n).
    • Preserves block indexes, start times, durations, and ordering.
  2. Short estimated TR rounded to zero (trdetect.ts)

    • Replaced 10 ms rounding with 1 us quantization.
  3. Full block scan and per-event Canvas state changes (drawing.js)

    • Uses binary search to select the visible block range.
    • Expands the candidate range by one block on both sides so ADC and other
      events extending beyond nominal block bounds are still considered.
    • Computes channel rows and colors once per frame.
    • Batches RF, phase, gradient, ADC, and trigger paths by channel.
    • Clips once per channel instead of calling save, clip, stroke, and
      restore for each event.
    • Changes visible-range lookup from O(n) to O(log n + v), where v is
      the number of visible blocks.
  4. Full waveform redraw on every pointer event (interaction.js,
    drawing.js, state.js, template.html, styles.css)

    • Adds a dedicated Canvas overlay for the waveform cursor.
    • Coalesces pointer events with requestAnimationFrame.
    • Keeps only the latest pointer state in each display frame.
    • Updates cursor and tooltip state without redrawing static waveforms.
    • Ignores unrelated global pointer movement when no viewer drag is active.
  5. Unnecessary WebGL trajectory redraw during waveform hover (kspace.js)

    • Separates the WebGL trajectory from the 2D axes/cursor overlay.
    • Waveform hover updates only the lightweight k-space overlay.
    • Redraws the WebGL trajectory only when the time window, camera,
      projection, point size, unit, or trajectory data changes.
    • Avoids repeated Canvas resize work during hover and camera animation.

Files Changed

  • src/editor/seqEditorProvider.ts
  • src/editor/webview/assets/drawing.js
  • src/editor/webview/assets/interaction.js
  • src/editor/webview/assets/kspace.js
  • src/editor/webview/assets/state.js
  • src/editor/webview/assets/styles.css
  • src/editor/webview/assets/template.html
  • src/pulseq/trdetect.ts
  • web/index.html
  • web/pulseq-bundle.js

@AssociatedPrimeIdeal

Copy link
Copy Markdown
Contributor Author

ute_3d_rf-sinc_rw_s0.9791666666666666_N96_FOV0.4_TR0.00242_TE0.00024000000000000003_C=1.zip
Here is a sequence containing 40,000 blocks that you can use for testing.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR targets performance bottlenecks when rendering and interacting with large Pulseq sequences, primarily by reducing algorithmic complexity in minimap/block selection and by decoupling “cursor hover” updates from full waveform / WebGL redraws.

Changes:

  • Optimizes minimap block-position construction to linear time in SeqEditorProvider.
  • Improves rendering performance by selecting visible blocks via binary search and batching waveform drawing by channel.
  • Adds a dedicated cursor overlay canvas and coalesces pointer updates to avoid full redraws on hover; splits k-space WebGL trajectory redraws from lightweight overlay redraws.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/editor/seqEditorProvider.ts Builds minimap block positions using a running cumulative sum (O(n) instead of O(n²)).
src/editor/webview/assets/drawing.js Refactors waveform rendering to draw only visible blocks and adds cursor overlay rendering.
src/editor/webview/assets/interaction.js Coalesces pointer events via requestAnimationFrame and updates overlays without full redraw.
src/editor/webview/assets/kspace.js Separates fast 2D overlay redraws from WebGL trajectory redraws; adds debug counters.
src/editor/webview/assets/state.js Introduces overlay canvas state and updates the draw scheduling to include k-space redraws.
src/editor/webview/assets/styles.css Styles the new cursor overlay canvas (#moc).
src/editor/webview/assets/template.html Adds the new overlay canvas element (<canvas id="moc">).
src/pulseq/trdetect.ts Changes TR estimation rounding to microsecond quantization to avoid rounding short TR to zero.
web/index.html Mirrors webview performance changes in the standalone web build (overlay canvas, coalesced pointer updates, batching).
web/pulseq-bundle.js Updates bundled Pulseq version and mirrors TR rounding behavior change.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +542 to +544
moc.width=r.width*dpr;moc.height=r.height*dpr;
moc.style.width=r.width+'px';moc.style.height=r.height+'px';
moctx.setTransform(dpr,0,0,dpr,0,0);
Comment thread web/index.html
Comment on lines +331 to +333
moc.width=r.width*dpr;moc.height=r.height*dpr;
moc.style.width=r.width+'px';moc.style.height=r.height+'px';
moctx.setTransform(dpr,0,0,dpr,0,0);
@bughht
bughht merged commit 17d73d3 into bughht:main Jul 11, 2026
8 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.

3 participants