Skip to content

PostView.handle_upload blocks main actor with synchronous file I/O #3705

@alltheseas

Description

@alltheseas

Problem

PostView.handle_upload(media:) calls getImage(media:) synchronously on the main actor before any await. This does file I/O (Data(contentsOf:)) and potentially video thumbnail generation on the main thread, which can cause UI hitches — especially with large media files.

Location: damus/Features/Posting/Views/PostView.swift around line 465-478

func handle_upload(media: MediaUpload) async -> Bool {
    mediaUploadUnderProgress = media
    let uploader = damus_state.settings.default_media_uploader
    
    let img = getImage(media: media)  // ← synchronous file I/O on main actor
    print("img size w:\(img.size.width) h:\(img.size.height)")
    
    async let blurhash = calculate_blurhash(img: img)
    // ...
}

Suggested fix

Move getImage(media:) and calculate_blurhash(img:) to a background context, then hop back to @MainActor for UI state updates and upload dispatch:

func handle_upload(media: MediaUpload) async -> Bool {
    mediaUploadUnderProgress = media
    let uploader = damus_state.settings.default_media_uploader

    let (img, blurhash) = await Task.detached {
        let img = getImage(media: media)
        let blurhash = calculate_blurhash(img: img)
        return (img, blurhash)
    }.value

    // Continue on MainActor with upload...
}

Impact

Low-to-medium — only manifests with large images/videos where the synchronous read is noticeable. Won't crash, but can cause frame drops during upload initiation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions