Skip to content

Draw the plan sheet cheaper: a shadow under it, commands in one field past twenty - #30

Merged
donislawdev merged 1 commit into
mainfrom
perf/w6-plan-sheet
Sep 29, 2026
Merged

donislawdev merged 1 commit into
mainfrom
perf/w6-plan-sheet

Conversation

@donislawdev

Copy link
Copy Markdown
Owner

W6 of the performance series that followed the external performance report - the plan sheet, report items G-6 and G-7. It closes the series.

What changes on screen

  • The sheet's shadow lies under it instead of on it. The shadow looks the same. The sheet's text is sharper, because an effect on an element turns ClearType off for everything under it.
  • Past twenty lines, commands stand in one read-only field with Copy all over it, instead of a box, a scroller and a Copy button per line. A single line is copied by selecting it in the field. This applies to both lists that use the same template - the equivalent commands before a run and the way back after one (GUI rule 5).
  • Entries the machine does not work without are named in one sentence per kind over the confirmation box, instead of one sentence per plan.

Why

  • G-6: an effect takes its whole subtree as input, so every caret blink and every tick of a run re-blurred the sheet. With software rendering - which is what WPF uses over Remote Desktop unless the application opts in - that was a third to half of a core while the confirmation box held the keyboard.
  • G-7: a stop over a whole scope printed 334 command boxes, 5013 of the sheet's 7185 elements, and the window stood still for half a second while they were built.
  • Found while measuring: on that same plan the footer grew a sentence per plan touching a critical entry and left the body holding the steps one unit tall, so the preview showed none of the steps.

Measured after the build, same probe (row-cost.ps1 -PlanCost), Release, no elevation

before after
elements in the sheet, stop over the whole Services scope (334 steps) 7185 2534
height of the body holding the steps 1 unit 221 units
sheet to idle, same plan 456-800 ms 302-411 ms (one run on a busy machine: 502-721)
processor with the caret in the box, software rendering 207-262 ms/s (look before this change, same process) 2-6 ms/s

How

  • New CommandBlock (lines, what is listed one at a time, whether they stand at once, the joined text, any, several) replaces six properties on Planned. Each section of commands binds its block as its data, so the Copy all button's name, content, tip, tag and visibility move into PlanCopyAllButton.
  • PlanSheetFrame holds the shape the sheet and PlanSheetShadow both wear. The shadow takes no hit tests.
  • ChromelessBox is split out of SearchFieldBox - the field of commands is the second box standing in a frame drawn by something else. Resources of a BasedOn style reach the box, guarded on the built window for all three boxes.
  • The gathering of critical sentences is in the window (PlanWords.Describe over a list), not in the core: the core's warnings reach the JSON of --dry-run, which is a public contract. The warning about a process taking others with it is not gathered, since its sentence names one entry.
  • PlanView.xaml comes down from 178 to 174 lines of markup, so the markup ceiling is lowered to 176.
  • The catalogue guard for tall samples asked about PlanSheet, which was tall only because of the margin that moved to its cell. No style or template sample is taller than a row today (the tallest is 86.6 of 96), so the guard now asks that every sample's flag equals its measurement.

Checks

  • Narrow test run over the plan, catalogue, contrast and text classes: all green except PluralGuards.What_the_window_admits_has_a_singular_for_one_entry, which reads "Running without administrator rights" in a session without elevation - a known failure of this session, not of this change.
  • Architecture tests 182 of 182.
  • Mutation register: 28 of 28 new, re-anchored and neighbouring entries caught, stale check clean.
  • The focus edge of the field lights on a shown window: #4A4A4A without focus, #65A3D8 with the keyboard in the field, read off pixels.

🤖 Generated with Claude Code

… past twenty

W6 of the performance series, report items G-6 and G-7.

The shadow is a sibling under the sheet rather than an effect on it. An
effect takes its whole subtree as input, so every caret blink in the
confirmation box and every tick of a run made WPF blur the sheet again -
where WPF draws in software, as over Remote Desktop, a third to half of a
core while the box held the keyboard. As a sibling it measures the same as
no shadow at all, and the sheet's text gets ClearType back. PlanSheetFrame
carries the shape both wear, so the shadow can only be cast by the sheet.

Past twenty lines a block of commands stands in one read-only text box
instead of a box, a scroller and a Copy button per line. A stop over a
whole scope printed 334 of those as 5013 of the sheet's 7185 elements. The
new CommandBlock type answers what a block holds, how it is shown and what
Copy all carries, for both the commands and the way back, and replaces six
properties on Planned. Each section of commands binds its block as its
data, so the Copy all button's name, content, tip, tag and visibility move
into its style. ChromelessBox is split out of SearchFieldBox, since the
field is the second box that stands in a frame drawn by something else.

Entries the machine does not work without are named in one sentence per
kind over the confirmation box, rather than one sentence per plan - on a
scope stop those sentences took the footer to 465 of 551 units and left the
steps one unit tall. Gathered in the window, not in the core, because the
core's warnings reach the JSON of --dry-run. The warning about a process
that takes others with it is not gathered, since its sentence names one
entry.

Measured after the build with the same probe: a scope stop's sheet has
2534 elements instead of 7185, its body 221 units instead of 1, and opens in
about 300-410 ms instead of 460-800. With the caret in the box and software
rendering the sheet costs 2-6 ms of processor a second, against 207-262 for
the look before this change in the same process.

The markup ceiling comes down to 176 now that PlanView.xaml is 174. The
catalogue guard for tall samples asks every sample instead of PlanSheet,
which is no longer tall once its margin moved to the cell.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Sep 29, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Advanced

Run ID: 9d17e7c8-8625-45cd-9684-872ededda73f


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@donislawdev
donislawdev merged commit 454c139 into main Sep 29, 2026
8 checks passed
@donislawdev
donislawdev deleted the perf/w6-plan-sheet branch September 29, 2026 13:40
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.

1 participant