Skip to content

text: Improve markdown preview responsiveness during rapid text updates#2371

Open
Third-Thing wants to merge 1 commit into
longbridge:mainfrom
Third-Thing:md-render-optimization
Open

text: Improve markdown preview responsiveness during rapid text updates#2371
Third-Thing wants to merge 1 commit into
longbridge:mainfrom
Third-Thing:md-render-optimization

Conversation

@Third-Thing

Copy link
Copy Markdown
Contributor

Problem

The markdown preview was applying every completed parse result, even when newer edits had already arrived. When typing or deleting quickly, slow parses could pile up and the preview would render old versions before catching up.

Solution

While parsing is still running, the preview keeps showing the last accepted parsed document. When parsing finishes, the result is accepted only if its update number is still current. If it is current, the preview is notified and renders the new document. If it is stale, the result is discarded and does not trigger a render.

After a parse finishes, the worker now drains queued edits and merges them into one latest update before parsing again. Before this change, queued edits could each trigger their own parse. During rapid input, this reduces both parsing and rendering work.

Improvements

  • Fewer follow-up parses when edits pile up
  • Fewer preview renders because stale parse results are ignored

Implemented-by: Codex GPT-5.5
Reviewed-by: Claude Opus 4.7 and Human

@Third-Thing

Copy link
Copy Markdown
Contributor Author

madcodelife pushed a commit that referenced this pull request May 26, 2026
## Description

This changes code block syntax highlighting to compute styles lazily and
reuse `SyntaxHighlighter` instances through a thread-local language
cache. This avoids repeated highlighter construction during markdown
parsing/render setup for large files with many code blocks.

It also avoids repeatedly recombining visible input highlight ranges
when the ranges are already disjoint.

I also tested #2371 against the same case, but it did not help with the
slowdown I was seeing.

I first noticed the issue in my side project, then reproduced the same
behavior in the example markdown editor. In local testing, Task Manager
showed lower CPU usage while editing with this implementation, memory
usage stayed about the same.

Adds regression coverage for code block equality and cached highlighter
refresh behavior when a language is registered after an initial
fallback.

AI assistance was used to help and prepare this PR. I manually reviewed
the resulting code and tested the performance difference before opening
the PR.

## Test File

I used this AI-generated markdown file to reproduce the issue and test
the change:


[refactor-opportunities.md](https://github.com/user-attachments/files/28234513/refactor-opportunities.md)

## Videos

### Before

<video
src="https://github.com/user-attachments/assets/dbcc45ab-f371-40c2-b6b5-1336fee995fe"
controls></video>

### After

<video
src="https://github.com/user-attachments/assets/4e3c0754-55b5-4d54-9eb6-a4261f940ad9"
controls></video>

## Tests

- `cargo test -p gpui-component code_block_`
- `cargo test -p gpui-component input::`
- `cargo test -p gpui-component text::`

## Checklist

- [x] I have read the [CONTRIBUTING](../CONTRIBUTING.md) document and
followed the guidelines.
- [x] Reviewed the changes in this PR and confirmed AI-generated code,
if any, is accurate.
- [x] Passed `cargo run` for story tests related to the changes.
- [x] Tested macOS, Windows, and Linux platform performance, if the
change is platform-specific.
AzureZee pushed a commit to AzureZee/gpui-component that referenced this pull request May 26, 2026
)

## Description

This changes code block syntax highlighting to compute styles lazily and
reuse `SyntaxHighlighter` instances through a thread-local language
cache. This avoids repeated highlighter construction during markdown
parsing/render setup for large files with many code blocks.

It also avoids repeatedly recombining visible input highlight ranges
when the ranges are already disjoint.

I also tested longbridge#2371 against the same case, but it did not help with the
slowdown I was seeing.

I first noticed the issue in my side project, then reproduced the same
behavior in the example markdown editor. In local testing, Task Manager
showed lower CPU usage while editing with this implementation, memory
usage stayed about the same.

Adds regression coverage for code block equality and cached highlighter
refresh behavior when a language is registered after an initial
fallback.

AI assistance was used to help and prepare this PR. I manually reviewed
the resulting code and tested the performance difference before opening
the PR.

## Test File

I used this AI-generated markdown file to reproduce the issue and test
the change:


[refactor-opportunities.md](https://github.com/user-attachments/files/28234513/refactor-opportunities.md)

## Videos

### Before

<video
src="https://github.com/user-attachments/assets/dbcc45ab-f371-40c2-b6b5-1336fee995fe"
controls></video>

### After

<video
src="https://github.com/user-attachments/assets/4e3c0754-55b5-4d54-9eb6-a4261f940ad9"
controls></video>

## Tests

- `cargo test -p gpui-component code_block_`
- `cargo test -p gpui-component input::`
- `cargo test -p gpui-component text::`

## Checklist

- [x] I have read the [CONTRIBUTING](../CONTRIBUTING.md) document and
followed the guidelines.
- [x] Reviewed the changes in this PR and confirmed AI-generated code,
if any, is accurate.
- [x] Passed `cargo run` for story tests related to the changes.
- [x] Tested macOS, Windows, and Linux platform performance, if the
change is platform-specific.
linyisu pushed a commit to linyisu/gpui-component that referenced this pull request May 29, 2026
)

This changes code block syntax highlighting to compute styles lazily and
reuse `SyntaxHighlighter` instances through a thread-local language
cache. This avoids repeated highlighter construction during markdown
parsing/render setup for large files with many code blocks.

It also avoids repeatedly recombining visible input highlight ranges
when the ranges are already disjoint.

I also tested longbridge#2371 against the same case, but it did not help with the
slowdown I was seeing.

I first noticed the issue in my side project, then reproduced the same
behavior in the example markdown editor. In local testing, Task Manager
showed lower CPU usage while editing with this implementation, memory
usage stayed about the same.

Adds regression coverage for code block equality and cached highlighter
refresh behavior when a language is registered after an initial
fallback.

AI assistance was used to help and prepare this PR. I manually reviewed
the resulting code and tested the performance difference before opening
the PR.

I used this AI-generated markdown file to reproduce the issue and test
the change:

[refactor-opportunities.md](https://github.com/user-attachments/files/28234513/refactor-opportunities.md)

<video
src="https://github.com/user-attachments/assets/dbcc45ab-f371-40c2-b6b5-1336fee995fe"
controls></video>

<video
src="https://github.com/user-attachments/assets/4e3c0754-55b5-4d54-9eb6-a4261f940ad9"
controls></video>

- `cargo test -p gpui-component code_block_`
- `cargo test -p gpui-component input::`
- `cargo test -p gpui-component text::`

- [x] I have read the [CONTRIBUTING](../CONTRIBUTING.md) document and
followed the guidelines.
- [x] Reviewed the changes in this PR and confirmed AI-generated code,
if any, is accurate.
- [x] Passed `cargo run` for story tests related to the changes.
- [x] Tested macOS, Windows, and Linux platform performance, if the
change is platform-specific.
@madcodelife

Copy link
Copy Markdown
Member

After #2400 was merged, I tested the scenario shown in the video(on macOS), and it looks very smooth now.

Do you mind giving it a try?

@Third-Thing

Copy link
Copy Markdown
Contributor Author

Yes that helps, which is not surprising. I flagged code blocks as a performance problem, but this more general optimization was found during investigation.

I just tested a markdown file with 637,707 characters and the rendering performance is still very slow. So for large files this optimization would still be useful.
Screencast_20260531_231632.webm

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.

2 participants