Skip to content

fix: update the table parser past its quadratic edit map - #675

Merged
Azganoth merged 2 commits into
mainfrom
chore/gfm-table-edit-map
Oct 10, 2026
Merged

Azganoth merged 2 commits into
mainfrom
chore/gfm-table-edit-map

Conversation

@Azganoth

Copy link
Copy Markdown
Owner

Summary

micromark-extension-gfm-table 2.1.1, reached through remark-gfm 4.0.1 and micromark-extension-gfm 3.0.0, resolves all of a document's tables through one edit map whose add finds an existing entry with a linear scan, so parsing time grows with the square of a document's table cells. Large table documents opened in tens of seconds or never opened, and folder search and replace parse with the same parser.

  • The lockfile now resolves 2.1.2, which micromark-extension-gfm's ^2.0.0 range already allows. No other resolved version changes, and 2.1.2 has the same dependencies and no install scripts.
  • The 2.1.1...2.1.2 source change that affects behavior is #17: add now looks entries up in a Map keyed by event index. add is the only way an entry is created, so each index holds at most one entry and the lookup returns the same entry the scan did; the other source changes are JSDoc and a brace-style rewrite of one condition.
  • CHANGELOG.md records the faster opening under Fixed.

Related Issue

Closes #671

Verification

  • pnpm check:frontend passed, including the corpus round trip, whose round-trip assertions over corpus/commonmark/, corpus/gfm/, and corpus/isolated/end-of-file/ run the parser with all of Leafdown's syntax extensions and are unchanged.

Manually verified in a release build of this branch on Windows 11, under a separate application identity in a 1280×900 window, driven through the WebView2 DevTools protocol with #638's method and fixtures (120-row, 6-column tables, opened from the welcome screen in a fresh process, timed until the document is shown and the main thread is free):

  1. The 500 KB table document opened in 4.33 s, against 45.8 s with 2.1.1 at 4804c81 in Determine Leafdown's large-document performance envelope #638. Forced layout was 1.28 s of it.
  2. The 1 MB table document opened in 9.83 s; with 2.1.1 it did not open within 180 s.

Not verified: folder search and replace over large table documents were not timed.

Notes

The 500 KB open still exceeds #638's 3 s open budget. What remains was not profiled here; #670 and #672 address other measured costs, and #638 plans to measure again after them.

@Azganoth Azganoth added the Maintenance Chore, refactor, dependency, or test work without user-facing change label Oct 10, 2026
@Azganoth Azganoth self-assigned this Oct 10, 2026
@github-project-automation github-project-automation Bot moved this to Backlog in Leafdown Oct 10, 2026
@Azganoth
Azganoth merged commit 7239c4e into main Oct 10, 2026
3 checks passed
@Azganoth
Azganoth deleted the chore/gfm-table-edit-map branch October 10, 2026 19:01
@github-project-automation github-project-automation Bot moved this from Backlog to Done in Leafdown Oct 10, 2026
Azganoth added a commit that referenced this pull request Oct 10, 2026
## Summary

After each edit, once typing paused for 200 ms, Milkdown's listener
plugin serialized the whole document so the session held a current copy
of its Markdown, and it serialized once more when the editor was
created. That blocked the main thread for about a third of a second in a
200 KB document of tables and about a second at 500 KB (#672).

The listener is removed. The session's `content` is now the Markdown a
document was opened, created, or last saved with, and each reader that
needs the current text gets it from the editor:

- Save and moving the open document already read the editor bridge first
and are unchanged.
- Reopening the same path reloads the editor whenever the document has
edits, not only when the file's text differs. The edits were discarded
to reopen it, and the session's text no longer shows them.
- An editor that lets go of an edited document that stays open hands its
Markdown to the session once. A remounted editor starts from that text,
and Save still writes the edits after a crash in the document surface
removes the editor, because the menu bar sits outside that error
boundary.
- Folder search treated the session's text changing as its cue to search
the open document again. It now waits 200 ms after a content-change
signal that the editor bridge fires on each edit without reading the
text.

The bridge's `getMarkdown` returns `null` instead of throwing while the
editor is still being created, so these readers fall back to the
session's text, which no edit can have changed yet.

## Related Issue

Closes #672

## Verification

- `openSession`: an edited document whose session text still matches the
file reloads when reopened after its edits are discarded.
- `document-screen`: edits fire the content signal without changing the
session's text; when the editor unmounts, the edited Markdown moves to
the session and the next editor mounts with it.
- `documentWorkflows`: Save writes the handed-over text once no editor
holds the document, and a clean or replaced document's editor is not
read.
- `folderSearchWorkflows`: the open document's results follow an edit
once it settles.
- Each of these tests failed with its fix disabled. The editor tests of
the listener were removed; the dirty-tracking assertions they held
remain.
- `pnpm check:frontend` passed after merging `main`.

Manually verified in a Windows 11 release build, before merging
#675–#678 from `main`:

1. In 205 KB and 505 KB documents of 120-row, 6-column tables, five
spaced keystrokes in a cell of the middle table were each followed by no
long animation frame. The keystroke's own frame, before the character
painted, took 69–85 ms at 205 KB and 181–226 ms at 505 KB, mostly the
input handler.
2. The same harness on `main` at 7cea7b9 recorded a 636–1179 ms timer
frame 230–290 ms after every keystroke at 205 KB.

Not verified: the release-build timings after merging #675–#678.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Maintenance Chore, refactor, dependency, or test work without user-facing change

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Update micromark-extension-gfm-table past its quadratic edit map

1 participant