Skip to content

feat: improve Markdown preview memory use - #2

Merged
lurenyang418 merged 1 commit into
mainfrom
agent/improve-markdown-preview-memory
Aug 12, 2026
Merged

feat: improve Markdown preview memory use#2
lurenyang418 merged 1 commit into
mainfrom
agent/improve-markdown-preview-memory

Conversation

@lurenyang418

Copy link
Copy Markdown
Contributor

What changed

  • release cached Markdown preview state when previews are hidden or documents disappear
  • guard asynchronous rendering with generations so stale work cannot overwrite newer state
  • downsample oversized local and remote preview images to a bounded decoded size
  • add copy controls and language labels to fenced code blocks
  • cap undo history dynamically while documents are in large-file mode

Why

Markdown previews and large editing sessions could retain more memory than necessary. In-flight preview work could also finish after a reset and mutate newer UI state. These changes bound retained preview/image/undo data and make render-state transitions deterministic.

User impact

Markdown previews use less memory, large images remain practical to display, code blocks can be copied directly, and large-file editing keeps a bounded undo history.

Validation

  • git diff --check
  • scripts/verify-host.sh Debug
  • 107 SwiftPM tests passed
  • host app, Quick Look extension, signing, sandbox entitlements, localization, and Markdown registration verified

@lurenyang418
lurenyang418 marked this pull request as ready for review August 12, 2026 08:16
Copilot AI lite review requested due to automatic review settings August 12, 2026 08:16
@lurenyang418
lurenyang418 merged commit f453c31 into main Aug 12, 2026
3 checks passed

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR reduces memory retention and improves determinism in the Markdown preview pipeline, while also adding small UX improvements (copyable fenced code blocks) and bounding undo history behavior for large files across the editor.

Changes:

  • Add render-generation invalidation and explicit reset semantics to MarkdownPreviewModel, plus tests to prevent stale async work from mutating newer state.
  • Downsample oversized preview images (local + remote) to cap decoded pixel memory usage.
  • Add copy controls and language labels to fenced code blocks; cap undo history when documents enter large-file modes.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
Tests/TildeMarkdownTests/MarkdownPreviewModelTests.swift Adds coverage for reset + generation-guarded rendering behavior.
Sources/TildeMarkdown/SecureAttachmentLoader.swift Adds image downsampling/re-encode path to bound decoded image memory for previews.
Sources/TildeMarkdown/MarkdownPreviewView.swift Introduces a copyable code block style with language label support.
Sources/TildeMarkdown/MarkdownPreviewModel.swift Implements generation-based invalidation and reset() to release retained preview state.
Sources/TildeEditor/EditorView.swift Adjusts presentation-state tracking and updates undo levels based on large-file disposition.
Sources/TildeEditor/EditorPresentationState.swift Includes LargeFileDisposition in the presentation state to trigger UI updates when it changes.
Sources/TildeEditor/EditorCoordinator.swift Updates undo levels after edits to react to large-file disposition transitions.
Sources/TildeApplication/DocumentRootView.swift Resets/releases preview snapshot/model when leaving preview or when the document disappears.
Suppressed comments (1)

Sources/TildeMarkdown/SecureAttachmentLoader.swift:297

  • Remote images are capped while downloading (policy.maximumAttachmentBytes), but oversized images can be re-encoded to PNG when downsampled. The resulting rendered.data can exceed policy.maximumAttachmentBytes, bypassing the intended per-attachment byte cap.
        let rendered = try PreviewImageDecoder.renderedData(
            from: data,
            source: source,
            pixelWidth: width,
            pixelHeight: height
        )
        return LocalImageAttachment(
            data: rendered.data,

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +176 to +180
func waitUntilStarted(revision: UInt64) async {
while !startedRevisions.contains(revision) {
await Task.yield()
}
}
Comment on lines +155 to +160
let rendered = try PreviewImageDecoder.renderedData(
from: data,
source: source,
pixelWidth: width,
pixelHeight: height
)
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