Skip to content
This repository has been archived by the owner on Aug 11, 2024. It is now read-only.

Typing is slow in big documents #310

Open
gordonbrander opened this issue May 13, 2022 · 4 comments
Open

Typing is slow in big documents #310

gordonbrander opened this issue May 13, 2022 · 4 comments
Labels
Bug Something isn't working Performance
Milestone

Comments

@gordonbrander
Copy link
Collaborator

gordonbrander commented May 13, 2022

Ideally, we fix this through converting to TextKit2 in #214.

The document doesn't have to be that large. Just medium.

Learnings from troubleshooting:

  • We're parsing twice. Once in textStorage delegate, and once in setEditor, for link search. That's two passes for each parse, so 4x passes. Too many.
  • Yet, disabling all parsing does not improve performance.
    • Removing the attribute application in the textStorage delegate does not improve perf. (Removes one parsing pass).
    • Removing the link-finding code does not improve perf. (Removes one parsing pass).
    • Removing both makes no difference.
  • Disabling all logging does not improve performance.
  • Rendering document-level styles once at init does not improve performance.
  • Replacing Range -> NSRange code did not improve performance
  • Retaining parsing, but disabling inline parsing within blocks (second pass) puzzlingly seems to improve performance a tiny bit, but this is probably an illusion? Either way, it's sufficiently bad that it doesn't solve anything.
  • Applying only font attributes and not parsing anything does not improve performance.
  • Passing NSTextStorage instead of NSMutableAttributedString does not improve performance (Some had reported this as a workaround, but it seems to make no difference. See Typing is slow in big documents #310 (comment))

Hypothesis:

  • Parsing is not the bottleneck
  • Rather the bottleneck seems to be text rendering. TextKit1 is a top-to-bottom text renderer.
    • The size of the text that needs to be laid out might matter. When text is small, more flow happens onscreen. This seems to affect perf somewhat.
  • ... or possibly NSString -> String conversion?

Possible solutions:

  • Would like to replace this with TextKit2, but this won't be available until iOS16
@gordonbrander gordonbrander added Bug Something isn't working Performance labels May 13, 2022
@gordonbrander gordonbrander added this to the Beta milestone Jun 12, 2022
@gordonbrander
Copy link
Collaborator Author

TextKit2 approach won't work, since UITextView cannot use TextKit2 in ios15 #214 (comment)

@gordonbrander
Copy link
Collaborator Author

Possibly related kyle-n/HighlightedTextEditor#25

@gordonbrander
Copy link
Collaborator Author

However, the textview performed terribly when I pasted in a lot of text (I used the full script of “A Streetcar Named Desire”, which is a couple thousand lines). It was not my syntax rules that were the problem either. Merely subclassing NSTextStorage, doing nothing fancy, was causing the app to lag and crash, outputting the opaque message in the debugger “Terminated due to memory error”. Some folks online were helped by changing the internal store from a NSAttributedString to NSTextStorage, but for me the problem remained. The solution that did work for me? Write the subclass in Objective-C. At first I didn’t know why this worked, but looking into it further, I believe it comes down to the conversion between Swift’s String and Objective-C’s NSString. The two have basically the same interface, but to convert between the two is not a constant time operation. Apparently, the conversion is O(n), leading to performance problems with very large amounts to text. https://www.thecope.net/2019/09/15/resolving-slow-performance.html

@gordonbrander gordonbrander changed the title Markup rendering is slow in big documents Typing is slow in big documents Jun 13, 2022
@gordonbrander
Copy link
Collaborator Author

I would prefer to solve this through migrating to TextKit2 now that it is available with iOS16. See #214.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Bug Something isn't working Performance
Projects
None yet
Development

No branches or pull requests

1 participant