Skip to content

Fix janky scrolling in markdown preview with code blocks#287050

Merged
mjbvz merged 4 commits into
microsoft:mainfrom
AshtonYoon:fix/janky-scrolling-in-markdown-preview
Mar 26, 2026
Merged

Fix janky scrolling in markdown preview with code blocks#287050
mjbvz merged 4 commits into
microsoft:mainfrom
AshtonYoon:fix/janky-scrolling-in-markdown-preview

Conversation

@AshtonYoon
Copy link
Copy Markdown
Contributor

@AshtonYoon AshtonYoon commented Jan 12, 2026

Fixes #278930

Summary

This PR fixes the scroll synchronization issues between the markdown editor and preview when scrolling through code blocks. Previously, scrolling through code blocks would cause noticeable jumps and stuttering due to:

  1. Inaccurate line-to-position mapping within multi-line code blocks
  2. Not accounting for padding when calculating scroll positions

Changes

1. Code block line tracking (scroll-sync.ts)

  • Added endLine calculation for fenced code blocks by counting newlines
  • Updated CodeLineElement to include optional endLine property
  • Enables accurate line-to-position mapping within multi-line code blocks

2. Padding-aware scrolling (scroll-sync.ts)

  • Implemented getContentBounds() function to calculate content area excluding padding
  • Used in both forward sync (editor → preview) and reverse sync (preview → editor)
  • Prevents jumps when scrolling through code blocks with padding

3. Scroll loop prevention

  • Preview side (index.ts): Changed scrollDisabledCount to use timer-based reset (50ms)
  • Editor side (preview.ts): Changed _isScrolling from counter to timer-based boolean (50ms)
  • Prevents infinite sync loops while maintaining smooth bidirectional synchronization

Result

Smooth scrolling through code blocks without any jumping or stuttering in both directions.

As-Is

Screen.Recording.2026-01-12.at.10.24.48.AM.mov

To-Be

Screen.Recording.2026-01-12.at.10.25.48.AM.mov

Fixes microsoft#278930

This commit fixes the scroll synchronization issues between the markdown
editor and preview when scrolling through code blocks:

1. **Code block line tracking**: Added endLine calculation for fenced
   code blocks by counting newlines, enabling accurate line-to-position
   mapping within multi-line code blocks.

2. **Padding-aware scrolling**: Implemented getContentBounds() to
   calculate scroll positions excluding padding, preventing jumps when
   scrolling through code blocks with padding.

3. **Scroll loop prevention**: Changed scroll disable flags from counters
   to timer-based booleans (50ms) to prevent infinite sync loops while
   maintaining smooth bidirectional synchronization.

The fix ensures smooth scrolling through code blocks without jumping or
stuttering in both directions (editor ↔ preview).
@AshtonYoon
Copy link
Copy Markdown
Contributor Author

@microsoft-github-policy-service agree

@AshtonYoon AshtonYoon marked this pull request as ready for review January 12, 2026 03:47
@RedCMD
Copy link
Copy Markdown
Contributor

RedCMD commented Mar 15, 2026

can confirm it fixes the scroll resetting issue

@symphonia117
Copy link
Copy Markdown

I can also confirm that this fixes the issue.

@vafeen
Copy link
Copy Markdown

vafeen commented Mar 26, 2026

When will it be merged if everything is ok?

mjbvz
mjbvz previously approved these changes Mar 26, 2026
Copy link
Copy Markdown
Collaborator

@mjbvz mjbvz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@mjbvz mjbvz added this to the 1.114.0 milestone Mar 26, 2026
@mjbvz mjbvz enabled auto-merge March 26, 2026 22:15
@mjbvz mjbvz merged commit 33fac91 into microsoft:main Mar 26, 2026
18 checks passed
AshtonYoon added a commit to AshtonYoon/vscode that referenced this pull request Apr 4, 2026
Two regressions from the merge of microsoft#287050:

1. preview.ts: The merge retained `this.#isScrolling = false` inside
   the early-return guard of `scrollTo()`, which was intentionally
   removed in the original PR. This resets the timer-based flag on
   the very first forward-sync call, allowing subsequent editor scroll
   events to re-trigger forward sync while reverse sync is in
   progress, causing the editor to jump back up.

2. index.ts: The PR converted `onUpdateView` from a decrement-counter
   to a timer-based approach but left initialization and resize
   handlers still using `scrollDisabledCount += 1` without a
   corresponding timer reset. The old scroll handler decremented the
   counter naturally; the new handler only returns early. As a result,
   after page load `scrollDisabledCount` stays at 1 indefinitely,
   blocking all preview-to-editor sync until the user scrolls the
   editor once.

Fixes:
- Remove the erroneous `this.#isScrolling = false` from scrollTo()
- Apply the same timer-reset pattern (200ms) to initialization and
  resize handlers so scrollDisabledCount is always auto-cleared

Fixes microsoft#307762
mjbvz added a commit that referenced this pull request May 1, 2026
…l-sync-regressions

markdown: fix scroll sync regressions introduced in #287050
@vs-code-engineering vs-code-engineering Bot locked and limited conversation to collaborators May 10, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Janky scrolling in markdown preview

7 participants