Inspector: Scrubben und Farbstopps pro Frame statt pro Eingabe auswerten #274

Closed
opened 2026-09-29 18:26:30 +02:00 by meleki · 1 comment
Owner

Aus #213 („Das Scrubben im Inspector und das Ziehen der Farbstopps im GradientBar lösen preview() weiter bei jeder Eingabe aus. Beide liegen außerhalb der drei Leinwände. Mit FramePreview wäre es je eine Zeile, falls gewünscht.“).

Befund

  • Seit #213 werten Scene View, Texture-Tab und Graph ein Ziehen höchstens einmal pro Frame aus (FramePreview, src/editor/framePreview.ts).
  • Das Scrubben eines Zahlenfelds im Inspector ruft state.preview() weiter bei jedem onInput auf (src/editor/inspector/previewHandlers.ts:104).
  • Dasselbe beim Ziehen eines Farbstopps im Verlauf von Vector Art (src/editor/vectorart/GradientBar.ts:136 → src/editor/inspector/shapeSection.ts:643).
  • Ein preview() ist ein volles Projekt-Update: Die Hierarchie baut neu, die Scene View zeichnet neu (gemessen in #265).
  • Gemessen ist das Scrubben selbst noch nicht. In #213 hat der Texture-Tab wegen Pixis doppelter Pointer-Events doppelt gezahlt, beim Scrubben ist dasselbe möglich.

Zu bauen (Vorschlag)

  • Vorher messen wie in #213: Wegwerf-Sonde, Moves im 8-ms-Takt, project-Events und ms pro Move, in einer Szene mit 120 Zusatzobjekten.
  • Beide Stellen rufen FramePreview.request() statt state.preview() und cancel() vor dem Commit, wie die Leinwände.
  • Tests: Unit für mehrere Eingaben in einem Frame (genau ein preview()), e2e-Check an einem echten Scrub im Inspector (der Wert am Ende stimmt, ein Undo-Schritt).

Offen (mit Vorschlag)

  1. Nur bauen, wenn die Messung etwas zeigt? Vorschlag: ja. Bringt es bei 120 Objekten weniger als 10 % pro Move, bleibt es beim heutigen Stand, und das Issue wird mit der Messung geschlossen.
Aus #213 („Das Scrubben im Inspector und das Ziehen der Farbstopps im `GradientBar` lösen `preview()` weiter bei jeder Eingabe aus. Beide liegen außerhalb der drei Leinwände. Mit `FramePreview` wäre es je eine Zeile, falls gewünscht.“). ## Befund - Seit #213 werten Scene View, Texture-Tab und Graph ein Ziehen höchstens einmal pro Frame aus (`FramePreview`, `src/editor/framePreview.ts`). - Das Scrubben eines Zahlenfelds im Inspector ruft `state.preview()` weiter bei jedem `onInput` auf (`src/editor/inspector/previewHandlers.ts:104`). - Dasselbe beim Ziehen eines Farbstopps im Verlauf von Vector Art (`src/editor/vectorart/GradientBar.ts:136` → `src/editor/inspector/shapeSection.ts:643`). - Ein `preview()` ist ein volles Projekt-Update: Die Hierarchie baut neu, die Scene View zeichnet neu (gemessen in #265). - Gemessen ist das Scrubben selbst noch nicht. In #213 hat der Texture-Tab wegen Pixis doppelter Pointer-Events doppelt gezahlt, beim Scrubben ist dasselbe möglich. ## Zu bauen (Vorschlag) - Vorher messen wie in #213: Wegwerf-Sonde, Moves im 8-ms-Takt, `project`-Events und ms pro Move, in einer Szene mit 120 Zusatzobjekten. - Beide Stellen rufen `FramePreview.request()` statt `state.preview()` und `cancel()` vor dem Commit, wie die Leinwände. - Tests: Unit für mehrere Eingaben in einem Frame (genau ein `preview()`), e2e-Check an einem echten Scrub im Inspector (der Wert am Ende stimmt, ein Undo-Schritt). ## Offen (mit Vorschlag) 1. **Nur bauen, wenn die Messung etwas zeigt?** Vorschlag: ja. Bringt es bei 120 Objekten weniger als 10 % pro Move, bleibt es beim heutigen Stand, und das Issue wird mit der Messung geschlossen.
meleki added the new label 2026-09-29 18:26:30 +02:00
admin added low-priority and removed new labels 2026-09-29 18:37:26 +02:00
admin added this to the Development project 2026-09-29 18:37:30 +02:00
admin moved this to Next in Development on 2026-09-29 18:37:32 +02:00
admin moved this to Done in Development on 2026-10-01 11:04:05 +02:00
admin moved this to Next in Development on 2026-10-01 11:25:33 +02:00
Author
Owner

Done in c4a9280 and d6171fd, wiki 6b01dae (Architecture, Development).

Measured first, as the issue asks
stein2, fixture project with 120 extra objects, 120 moves 8 ms apart, three runs each:

before after
Scrub: project events 236 51 to 61
Scrub: ms per move 45 to 50 22 to 27
Colour stop: project events 238 50 to 51
Colour stop: ms per move 44 to 49 22
  • Both gestures paid twice, as the issue suspected: about two preview() per move, because Pixi repeats each pointer move shortly after.
  • The threshold of the issue (at least 10 % per move) is passed with about 50 %.
  • One preview() still costs 13 to 17 ms. That price per frame is what remains.

What changes (c4a9280)

  • Inspector rows: previewingHandlers still writes the model on every input but tells the editor at most once per frame. The commit drops a waiting preview first.
  • Colour stops: the preview handler of the GradientBar in shapeSection.ts does the same.
  • Wider than the issue describes: the row handlers also serve typing, the arrow keys and the colour picker. All of them preview once per frame now.

Two findings, fixed as well (d6171fd)

  • Pixel art tab: the colour of a palette swatch and the opacity of a layer follow the same rule (PixelArtSide.ts).
  • Curve tab: the t and v fields of the picked point too (CurveCanvas.movePicked).
  • Also fixed: when the colour picker ended on the colour it started from, the model was put back but nobody was told, so the previewed colour stayed on screen. commitColor now says so, as the opacity already did.
  • The gain was not measured for either tab, only the behaviour is tested.

Tests (on melektaus-atx)

c4a9280   gate          198 files, 2907 tests, CHECK EXIT 0 (2903 + 4)
          e2e, full     ALL PASSED - 1616 checks, E2E EXIT 0 (1615 + 1)
          smokes        24 / 19 / 21, SMOKES EXIT 0
d6171fd   gate          198 files, 2911 tests, CHECK EXIT 0 (2907 + 4)
          e2e 47,48,53  ALL PASSED - 117 checks
  • Eight new unit tests in tests/editor/frame-preview.test.ts: row, colour stop, palette colour, opacity, curve fields and the return to the starting colour. They check that every input is in the model at once, that there is one preview() per frame and that nothing is left for the next frame after the commit (one undo step).
  • One new e2e check in module 02: a held scrub counts project events against frames. Measured 10 events in 12 frames, and the value is there before the release.
  • Eleven unit counter-checks, all work (four for c4a9280, seven for d6171fd). They ran on stein2, not in the container.
  • The browser counter-check for the scrub works too: the build went through, the new check then fails with 50 events in 16 frames.
  • For d6171fd there is no new e2e check and no counter-check in the browser, and neither the full suite nor the smokes ran for it on melektaus-atx.
  • CI is switched on again. Run 275 for d6171fd was still running when this was written, its result is not in here.
Done in `c4a9280` and `d6171fd`, wiki `6b01dae` (*Architecture*, *Development*). **Measured first, as the issue asks** stein2, fixture project with 120 extra objects, 120 moves 8 ms apart, three runs each: | | before | after | |---|---|---| | Scrub: `project` events | 236 | 51 to 61 | | Scrub: ms per move | 45 to 50 | 22 to 27 | | Colour stop: `project` events | 238 | 50 to 51 | | Colour stop: ms per move | 44 to 49 | 22 | - Both gestures paid twice, as the issue suspected: about two `preview()` per move, because Pixi repeats each pointer move shortly after. - The threshold of the issue (at least 10 % per move) is passed with about 50 %. - One `preview()` still costs 13 to 17 ms. That price per frame is what remains. **What changes** (`c4a9280`) - **Inspector rows:** `previewingHandlers` still writes the model on every input but tells the editor at most once per frame. The commit drops a waiting preview first. - **Colour stops:** the `preview` handler of the `GradientBar` in `shapeSection.ts` does the same. - **Wider than the issue describes:** the row handlers also serve typing, the arrow keys and the colour picker. All of them preview once per frame now. **Two findings, fixed as well** (`d6171fd`) - **Pixel art tab:** the colour of a palette swatch and the opacity of a layer follow the same rule (`PixelArtSide.ts`). - **Curve tab:** the `t` and `v` fields of the picked point too (`CurveCanvas.movePicked`). - **Also fixed:** when the colour picker ended on the colour it started from, the model was put back but nobody was told, so the previewed colour stayed on screen. `commitColor` now says so, as the opacity already did. - The gain was not measured for either tab, only the behaviour is tested. **Tests** (on `melektaus-atx`) ``` c4a9280 gate 198 files, 2907 tests, CHECK EXIT 0 (2903 + 4) e2e, full ALL PASSED - 1616 checks, E2E EXIT 0 (1615 + 1) smokes 24 / 19 / 21, SMOKES EXIT 0 d6171fd gate 198 files, 2911 tests, CHECK EXIT 0 (2907 + 4) e2e 47,48,53 ALL PASSED - 117 checks ``` - Eight new unit tests in `tests/editor/frame-preview.test.ts`: row, colour stop, palette colour, opacity, curve fields and the return to the starting colour. They check that every input is in the model at once, that there is one `preview()` per frame and that nothing is left for the next frame after the commit (one undo step). - One new e2e check in module 02: a held scrub counts `project` events against frames. Measured 10 events in 12 frames, and the value is there before the release. - Eleven unit counter-checks, all work (four for `c4a9280`, seven for `d6171fd`). They ran on stein2, not in the container. - The browser counter-check for the scrub works too: the build went through, the new check then fails with 50 events in 16 frames. - For `d6171fd` there is no new e2e check and no counter-check in the browser, and neither the full suite nor the smokes ran for it on `melektaus-atx`. - CI is switched on again. Run 275 for `d6171fd` was still running when this was written, its result is not in here.
admin moved this to Done in Development on 2026-10-01 12:08:19 +02:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: meleki/feuerwerk#274