Skip to content

[lexical-y] Speed follow-ups for paired format runs (layout 3) #9787

Open

Description

@zurfyx

Layout 3 (#9777) pairs each format run's end with its opener, so concurrent formats of one key nest instead of cutting each other short. It costs speed on open, on building the Yjs document and on format-heavy paths. These are the costs accepted for its first release, measured on production builds against main, 6 runs each:

Path Cost vs main
Opening a 20,000-word document +17%
Building its Yjs document +27%
A 2,000-line highlighted code block: open +26%
same: building its Yjs document +29%
same: a collaborator's edit inside it +14%
same: typing at a token edge +20%
same, with raw bold in the code: open / typing +31% / +23%
Repeated formatting at one spot +39%
Typing at a hot spot +29%
Format on/off cycles +30%
A collaborator's format +13%
A long note session +12%

Where the extra time goes when a 20,000-word document opens, per open: building the index of ends about 51 ms, repairing copied ends on load about 22 ms, the rest of the paired fold about 27 ms, and GC about 22 ms.

Follow-ups, each as its own pull request with before and after numbers on these paths, and the same unit, randomized and soak checks as #9777:

  • Read each line once per open. Today a line can be folded once per pass while the document opens. One fold per open should take most of the paired fold's share off the open and Yjs-build paths.
  • Repair copied ends lazily. Today every load scans the whole insert set for copied ends (about 22 ms above). Repairing a copied end only when it is first read would remove most of that, but it must keep undo across origins, remote-origin undo managers and mixed transactions correct; an earlier eager-skip attempt broke those cases, so the design comes first.
  • Index ends lazily, per container, instead of document-wide on the first fold (about 51 ms above).
  • Highlighted code blocks. Re-segmenting code rewrites runs often; bring its open, Yjs build and typing costs down, starting from the rows above.

Target for this list: every path above within +10% of main.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions