Skip to content

perf(mobile): avoid reparsing unchanged Markdown - #7649

Merged
brow merged 1 commit into
mainfrom
mobile-markdown-stability
Sep 15, 2026
Merged

brow merged 1 commit into
mainfrom
mobile-markdown-stability

Conversation

@brow

@brow brow commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

When a channel screen updates, Buzz Mobile can parse and format a message again even when its text has not changed. This repeated work runs on the same thread that handles taps and updates the screen.

The current Markdown library, gpt_markdown 1.2.1, checks whether the objects used to render mentions, emoji, and channel links have changed. Buzz creates new objects on every message rebuild, so the library parses the message again. This change reuses those objects while their inputs stay the same. Changes to labels, mention targets, emoji, media details, or available actions still update the message. Taps continue to use the latest action handlers.

In a synthetic test with the production message widget, ten unchanged rebuilds caused 30 parser calls before this change and zero after it. The first render still requires parsing. This test measures repeated parsing, not overall screen speed.

Validation:

  • All 91 focused message tests and 2,127 mobile tests passed. The new regression test fails with the original code. Tests also cover changed message data and current tap actions.
  • Static checks across the repository, desktop and Tauri tests, and desktop and web builds passed. The full local test run hit an existing Rust ACP keepalive timing failure. Its exact retry passed, and all checks skipped after that failure were run separately and passed.

Signed-off-by: Tom Brow <tomb@block.xyz>
@brow

brow commented Sep 14, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@github-actions

github-actions Bot commented Sep 14, 2026

Copy link
Copy Markdown

🔐 Codex Security Review

Status: review required for the current range.

The current range is a9dd4d3bd771b47f0efb4e7f6f7329a5921372b5...6af20bc4c226bb79f915121d0c3c5e006c91e4cb.
A new review must complete for this exact range. When manual authorization
is required, a Block organization member must comment exactly
@buzz-security-review 6af20bc4c226bb79f915121d0c3c5e006c91e4cb to authorize a new review.
Any previous review applies only to its recorded range.

@brow

brow commented Sep 14, 2026

Copy link
Copy Markdown
Contributor Author

@builderbot review

@brow

brow commented Sep 14, 2026

Copy link
Copy Markdown
Contributor Author

@buzz-security-review 6af20bc

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 14, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-15T18:05:27.424474Z 6af20bc Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Another round soon, please!

Reviewed commit: 6af20bc4c2

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@brow

brow commented Sep 14, 2026

Copy link
Copy Markdown
Contributor Author

@buzz-security-review 6af20bc

1 similar comment
@brow

brow commented Sep 15, 2026

Copy link
Copy Markdown
Contributor Author

@buzz-security-review 6af20bc

@brow
brow marked this pull request as ready for review September 15, 2026 17:59
@brow
brow requested a review from a team as a code owner September 15, 2026 17:59
@brow
brow enabled auto-merge (squash) September 15, 2026 17:59

@jedwards27 jedwards27 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

:bot: Jude’s code review agent — APPROVE at exact head 6af20bc4c226bb79f915121d0c3c5e006c91e4cb (base 7c789dee09d198469bded1cb5be902eaf5562ad9).

No author-actionable defects found.

The cache contract is coherent end to end:

  • _InlineComponentInputs snapshots all changed rendering inputs by value—content/rendered content, mention labels and bindings, agent/channel data, emoji, size, raw tags, and action presence—so meaningful changes invalidate while equivalent rebuilds preserve inline-component identity (mobile/lib/features/channels/message_content/inline_components.dart:32-135).
  • Stable forwarding closures read handler refs refreshed on every build; adding/removing actions participates in invalidation. Mention, channel, reply, more, and media callbacks therefore remain current without forcing Markdown reparsing (inline_components.dart:18-31; message_content.dart:181-207).
  • Raw-tag invalidation refreshes media metadata and regenerated spans; tests cover updated alt text and action removal (message_content.dart:214,292-342; message_content_stability_test.dart:98-154).
  • Retention is per mounted widget, not static/global. Message rows are keyed by event ID, and unmounting releases hook state, so lazy-list recycling does not transfer cached inputs between logical messages (message_bubble.dart:103-143; message_list.dart:776-825).
  • This targets the actual dependency seam: gpt_markdown 1.2.1 regenerates when its expression changes or config.isSame fails, and that comparison uses inline-component element identity. Mutation checks confirmed that removing memoization fails the identity regression and stopping ref refresh fails latest-handler assertions.

Exact-head evidence:

  • Full mobile tests: 2,127 passed.
  • flutter analyze: no issues; format/check task clean.
  • Directly affected message suites: 97 passed.
  • CI, DCO, Semgrep, and zizmor are successful; irrelevant jobs are skipped.
  • Live PR head was rechecked immediately before this review.

Residual confidence gaps, with author action: none:

  1. The PR-body synthetic 30 → 0 parser-call count was not independently reproduced because its instrumentation is not checked in. The checked-in identity test plus mutation failure causally verifies the production cache predicate, but not that exact numerical measurement. Verification owner: reviewer/performance tooling.
  2. No native iOS visual/VoiceOver/tap/recycling journey or same-device frame-time cohort was run. Widget/full-suite coverage is strong; remaining risk is native-only lifecycle or rendering behavior outside that harness. Verification owner: reviewer/release tooling.

@brow
brow merged commit 98a6db5 into main Sep 15, 2026
70 checks passed
@brow
brow deleted the mobile-markdown-stability branch September 15, 2026 18:11
brow added a commit that referenced this pull request Sep 15, 2026
…ush-cache-offload

* commit '41c5ace93740261ee5a5d962c2a17e8d846c2c1b':
  perf(mobile): move profile sig checks off main thread (#7648)
  perf(mobile): avoid redundant message list sorting (#7647)
  perf(mobile): avoid reparsing unchanged Markdown (#7649)
  Fix desktop onboarding regressions (#7659)
  Deduplicate thread context by ACP session delivery (#7620)
  feat(mobile): hard-block under-18 users on the store age signal (#4665)
  Document incoming Buzz turn structure (#7624)
  Refresh desktop onboarding flow (#7528)
  Fix Apple Silicon iOS simulator builds (#7646)

Signed-off-by: Tom Brow <tomb@block.xyz>
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