perf: fix editor lag on large documents (55K+ lines) (#701)#760
Merged
perf: fix editor lag on large documents (55K+ lines) (#701)#760
Conversation
Root cause: multiple O(n) operations on every keystroke for large documents — SwiftUI binding writeback (2.6MB String copy), completion adapter reading full document text, and tree-sitter edit cancellation preventing highlight queries from completing. Fixes: - Debounce SwiftUI text binding writeback (150ms for docs >500KB) to eliminate per-keystroke 2.6MB String copy into SwiftUI - Set isUpdateFromTextView flag to prevent echo loop through updateNSViewController on binding writeback - Read only prefix substring in completionOnCursorMove instead of full document — O(prefix_length) vs O(document_length) - Extract 10KB windowed text in completionSuggestionsRequested instead of copying full document - Cap completion prefix at 100 chars — dismiss stale context that would read thousands of characters - Skip keyword auto-uppercase for documents >500KB to prevent cascade edits that double per-keystroke cost - Increase highlight chunk limit from 2 to 8 per cycle for large documents to cover full viewport - Only cancel highlight queries (.access) on new edits, not pending edits — prevents edit starvation that blocks all highlighting - Small highlight queries (<8KB) bypass executor queue to avoid being blocked by pending large parse operations Limitation: tree-sitter SQL grammar takes 700-950ms for incremental parse on 2.6MB documents. Syntax highlighting appears 1-2s after typing stops. This is a tree-sitter performance characteristic, not fixable without grammar optimization or a regex fallback highlighter. Closes #701
- Set isUpdateFromTextView immediately (synchronously) before debounce Task — prevents SwiftUI from overwriting typed chars during 150ms delay - Remove unsafe queue bypass for small queries — use executor's sync path which acquires the lock properly, fall through to async if busy - Raise prefix cap from 100 to 500 chars — prevents false dismissal after large paste where replacementRange is briefly stale - Remove double blank line in Highlighter.swift
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes editor lag when typing in documents with 55K+ lines / 2.6MB+. Root cause: multiple O(n) operations running synchronously on every keystroke.
Changes (6 files)
Tree-sitter limitation
SQL grammar takes 700-950ms for incremental parse on 2.6MB documents. Highlighting appears 1-2s after typing stops. This is inherent to tree-sitter at this document size.
Test plan
Closes #701