Skip to content

Reduce memory used when saving Performance data for offline viewing - #10034

Open
hkarmoush wants to merge 2 commits into
flutter:masterfrom
hkarmoush:reduce-perf-export-memory
Open

hkarmoush wants to merge 2 commits into
flutter:masterfrom
hkarmoush:reduce-perf-export-memory

Conversation

@hkarmoush

@hkarmoush hkarmoush commented Oct 10, 2026 •

Copy link
Copy Markdown

Fixes #10010

Saving Performance data wrote the Perfetto trace as a JSON array of numbers. jsonEncode then does roughly two string writes per trace byte, so a ~50 MB trace becomes a ~184 MB file and a very large number of string fragments in the browser, which is what runs the tab out of memory.

This changes the export to:

  • write the trace as a base64 string under a new traceBinaryBase64 key (about 1.33x the trace size instead of about 3.7x). toJson() keeps a ByteData view and the existing toEncodable does the base64 step, so "Review History" on disconnect still holds the trace without copying it.
  • keep reading the old traceBinary list format, so existing exported files still load. Older DevTools versions opening a new file will see no trace rather than throwing a type error, because the key is different.
  • fix ByteDataEncodeDecode to encode only the bytes in the view, not the whole backing buffer.
  • allocate Uint8ListRingBuffer.merged once at its exact size instead of letting BytesBuilder round up to a power of two.
  • show an error notification instead of failing when the data is too large to turn into one JSON string (still around 400 MB of trace).
  • revoke the download Blob URL once the download has started.

Not changed: import still reads the whole file as one string, and traces over roughly 400 MB would need a different file format.

Tests: added round-trip tests for the new format, the legacy list and Uint8List inputs, an in-memory ByteData, a sub-view of a larger buffer, and a size check. Also updated the existing toJson assertion. I have not yet measured the memory difference in a browser against a real 2 minute recording.

Pre-launch Checklist

General checklist

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • I read the Tree Hygiene wiki page, which explains my responsibilities.
  • I read the Flutter Style Guide recently, and have followed its advice.
  • I signed the CLA.
  • I updated/added relevant documentation (doc comments with ///).

Issues checklist

  • I listed at least one issue that this PR fixes in the description above.

Tests checklist

  • I added new tests to check the change I am making...

Feature-change checklist

  • This PR does change the DevTools UI or behavior and...
    • I added an entry to packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md.
    • I ran the DevTools app locally to manually verify my changes.

The Perfetto trace was exported as a JSON array of numbers, which makes
jsonEncode do roughly two string writes per trace byte and can exhaust the
browser's memory for large traces. Export it as a base64 string under a new
key instead, and keep reading the legacy list format so older files still
load.

Also:
- Only encode the bytes in a ByteData view when converting to base64.
- Allocate Uint8ListRingBuffer.merged once at its exact size.
- Show an error instead of crashing when the data is too large to export.
- Revoke the download Blob URL after the download starts.

Fixes flutter#10010
@hkarmoush
hkarmoush requested review from a team and kenzieschmoll as code owners October 10, 2026 01:50
@hkarmoush
hkarmoush requested review from srawlins and removed request for a team October 10, 2026 01:50

@gemini-code-assist gemini-code-assist Bot 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.

Code Review

This pull request optimizes memory usage and file size when saving and loading performance trace data. It introduces base64 encoding for the Perfetto trace binary instead of the legacy JSON array of numbers, while maintaining backwards compatibility. It also optimizes buffer merging in Uint8ListRingBuffer, ensures only the active view of ByteData is encoded, handles potential RangeError during large exports, and defers revoking object URLs on the web to prevent download cancellations. There are no review comments, so I have no feedback to provide.

This branch has not been deployed

No deployments
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.

[Performance][Windows] Saving Performance data for offline viewing causes multi GB RAM spike and can OOM/crash DevTools

1 participant