Skip to content

fix(web): decode timeline image attachments asynchronously - #19923

Merged
juliusmarminge merged 3 commits into
pingdotgg:mainfrom
rohan-patnaik:fix/image-scroll-performance
Oct 20, 2026
Merged

juliusmarminge merged 3 commits into
pingdotgg:mainfrom
rohan-patnaik:fix/image-scroll-performance

Conversation

@rohan-patnaik

@rohan-patnaik rohan-patnaik commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Large stored image attachments can stall the timeline during decoding. Add decoding="async" to the regular user attachment image, including the existing HEIC wrapper. This keeps image URLs and layout intact and applies to web and the shared Electron UI.

Fixes #19922. Maintainer takeover of #19923; original implementation and synthetic reproduction by @rohan-patnaik. Original author commit retained; main merged without rebasing.

At 25b51d885d:

  • 195 existing tests pass across MessagesTimeline.logic.test.ts, timelineScrollAnchoring.test.tsx, and ExpandedImagePreview.test.ts. Added tests: 0 before → 0 after; no attribute-only assertions.
  • Web typecheck, scoped lint, formatting, and git diff --check pass.
  • Fresh independent Claude Opus 5.5 and Codex GPT-6 Sol full-diff reviews: one round, no code findings.

The running app was measured in headless Linux Chromium at 1280 × 800 with 13 synthetic 4590 × 8160 stored JPEGs and fresh blob URLs for cold decoding. Three six-second unrecorded trials had maximum frame gaps of 2800/2917/2950 ms on the base versus 267/2567/1317 ms with async decoding. P95 was 17–33 ms on the base and 83–133 ms after. All 13 images loaded. These results support reducing the worst freeze, not uniformly smoother frames; async decoding can defer visible pixels. Raw frame intervals. Current uploads resize images; this fixture represents stored originals.

Before (base, settled images):
Before: stored synthetic image attachments

After (head, same viewport, fixture, and scroll position):
After: same settled image layout

Before recording · After recording. Recording adds overhead and is separate from the measurements.

Not verified: macOS, Windows, iOS, Android, native Electron desktop, Safari, Firefox, or remote/relay/tunnel browsers. No provider turn was sent. Human review of the performance tradeoff remains required; unmerged.

Model: GPT-6.1 Sol (high), Codex harness in T3 Code. Tests: GPT-6 Astra (high); reviews: Claude Opus 5.5 and GPT-6 Sol.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XS 0-9 changed lines (additions + deletions). labels Oct 15, 2026
@coderabbitai

coderabbitai Bot commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Path: .coderabbit.config.ts
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 1879268c-3409-48dd-9256-32d5f5ceddd1
📥 Commits

Reviewing files that changed from the base of the PR and between 1383e03 and ee6a3c0.

📒 Files selected for processing: 1
  • apps/web/src/components/chat/MessagesTimeline.tsx

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 7 remain after this review.

📝 Walkthrough

The user-message image preview now requests asynchronous image decoding.

Changes: User-message image preview

Layer / File(s) Summary
Set image decoding hint
apps/web/src/components/chat/MessagesTimeline.tsx
The user-message image preview requests asynchronous decoding.

Priority: ➖ Normal

Estimated code review effort: 1 (Trivial) | ~2 minutes

Change: Bug fix · Severity of issue fixed: Medium

Suggested reviewers: maria-rcks

Merge Risk: ⚪ Minimal · up to ee6a3

No actionable merge-blocking risk remains from this change.

Pre-merge checks: Passed 4
Check name Status Explanation
Title check Passed The title clearly and concisely describes the main change: enabling asynchronous decoding for timeline image attachments.
Description check Passed The description covers the problem, change, scope, linked issue and PR context, verification results, performance measurements, screenshots, recordings, limitations, and agent details. It is sufficien…
Linked Issues check Passed Issue #19922 requires asynchronous decoding for regular user attachment images while preserving image URLs, pixels, layout, and expansion behavior. The PR adds decoding="async" to the `AttachmentIma…
Out of Scope Changes check Passed The whole-PR diff contains one added decoding="async" attribute in apps/web/src/components/chat/MessagesTimeline.tsx. The change directly addresses issue #19922 and does not add unrelated behavior…
Full details: Description check

Explanation

The description covers the problem, change, scope, linked issue and PR context, verification results, performance measurements, screenshots, recordings, limitations, and agent details. It is sufficiently complete for the template.

Full details: Linked Issues check

Explanation

Issue #19922 requires asynchronous decoding for regular user attachment images while preserving image URLs, pixels, layout, and expansion behavior. The PR adds decoding="async" to the AttachmentImage instance in MessagesTimeline.tsx. AttachmentImage forwards this prop to its regular <img> and existing HeicImage wrapper, whose <img> also receives the prop. The diff does not change the source URL, layout classes, or expansion handler. The reported existing tests and validation support the change. No issue requirement mandates a new automated test.

Full details: Out of Scope Changes check

Explanation

The whole-PR diff contains one added decoding="async" attribute in apps/web/src/components/chat/MessagesTimeline.tsx. The change directly addresses issue #19922 and does not add unrelated behavior, refactoring, or files.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@juliusmarminge

Copy link
Copy Markdown
Member

Taking over this one as maintainer for composer-chat-01. Resuming the existing worktree, preserving the focused async decode hint and original author commits; I will verify it on current main before pushing.

@juliusmarminge juliusmarminge self-assigned this Oct 19, 2026
@juliusmarminge
juliusmarminge merged commit da26f1e into pingdotgg:main Oct 20, 2026
25 checks passed
Pipyakas pushed a commit to Pipyakas/t3code that referenced this pull request Oct 21, 2026
…#19923)

Co-authored-by: Rohan Patnaik <rohan-patnaik@users.noreply.github.com>
Co-authored-by: Julius Marminge <julius0216@outlook.com>
(cherry picked from commit da26f1e)
TheDarkPhantom added a commit to TheDarkPhantom/avicode that referenced this pull request Oct 26, 2026
…#19923)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XS 0-9 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Large stored image attachments freeze scrolling while decoding

2 participants