Skip to content

perf: byte budget for image cache, fix video thumbnail rebuild, clear byte cache on room exit#2987

Draft
9clg6 wants to merge 1 commit intomainfrom
perf/targeted-memory-improvements
Draft

perf: byte budget for image cache, fix video thumbnail rebuild, clear byte cache on room exit#2987
9clg6 wants to merge 1 commit intomainfrom
perf/targeted-memory-improvements

Conversation

@9clg6
Copy link
Copy Markdown
Collaborator

@9clg6 9clg6 commented Apr 3, 2026

Summary

Three targeted memory improvements following the perf audit. No functional changes — all existing behavior is preserved.

1. Byte budget for MxcImageCacheManager (50 MB)

The cache was limited to 100 entries with no size awareness. 100 images at 5 MB each = 500 MB of Dart heap. Now tracks _totalBytes and evicts LRU entries when either the count (100) or byte budget (50 MB) is exceeded.

// Before: count-only eviction
while (_imageCache.length >= _size) { _imageCache.remove(...); }

// After: count + byte budget eviction
while (_imageCache.length >= _maxCount ||
    (_totalBytes + imageData.length > _maxBytes && _imageCache.isNotEmpty)) {
  _totalBytes -= _imageCache[oldest]!.length;
  _imageCache.remove(oldest);
}

Also adds clear() method used by point 3 below.

2. Fix video thumbnail re-generation on every rebuild

_ImageWidget was a StatelessWidget whose build() called:

FutureBuilder(future: event?.room.generateVideoThumbnail(matrixVideoFile), ...)

Every setState() from a parent created a new Future, re-running generateVideoThumbnail() — which writes a temp file (mobile) or creates a blob URL (web), calls VideoThumbnail.thumbnailData(), and decodes the bitmap.

Fix: convert to StatefulWidget, compute the Future once in initState() and refresh in didUpdateWidget() only when data or event changes.

3. Clear raw byte cache on room exit

chat.dart dispose() already called PaintingBinding.instance.imageCache.clear() to evict decoded bitmaps. The compressed byte cache (MxcImageCacheManager) was never cleared — bytes accumulated across room navigations indefinitely. Now cleared alongside the decoded bitmap cache.

Test plan

  • fvm flutter analyze clean
  • Navigate between rooms — video thumbnails display correctly, no repeated network/decode calls
  • Memory in Chrome DevTools stable after leaving rooms (heap does not grow linearly with room count)
  • Images in chat display correctly after cache eviction

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 3, 2026

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 0fa47f34-22cb-45c7-aa73-1c8a2abc94cb

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch perf/targeted-memory-improvements

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

codescene-delta-analysis[bot]

This comment was marked as outdated.

codescene-delta-analysis[bot]

This comment was marked as outdated.

@9clg6 9clg6 force-pushed the perf/targeted-memory-improvements branch from 64e8128 to ad62574 Compare April 3, 2026 11:05
codescene-delta-analysis[bot]

This comment was marked as outdated.

@9clg6 9clg6 force-pushed the perf/targeted-memory-improvements branch from ad62574 to 169ae12 Compare April 3, 2026 11:22
codescene-delta-analysis[bot]

This comment was marked as outdated.

@9clg6 9clg6 force-pushed the perf/targeted-memory-improvements branch from 169ae12 to 466b2a4 Compare April 3, 2026 11:24
codescene-delta-analysis[bot]

This comment was marked as outdated.

@9clg6 9clg6 force-pushed the perf/targeted-memory-improvements branch from 466b2a4 to 218e367 Compare April 3, 2026 11:37
codescene-delta-analysis[bot]

This comment was marked as outdated.

@9clg6 9clg6 self-assigned this Apr 3, 2026
@9clg6 9clg6 force-pushed the perf/targeted-memory-improvements branch from 218e367 to 43b4200 Compare April 3, 2026 11:43
codescene-delta-analysis[bot]

This comment was marked as outdated.

…ed guards

- MxcImageCacheManager: add 150 MB byte budget alongside the 100-entry
  count limit; track _totalBytes, evict LRU when over budget; reject
  images larger than the budget to preserve the invariant; add clear().
  150 MB covers compressed bytes (JPEG/PNG) — decoded bitmaps are handled
  separately by PaintingBinding.imageCache (100 MB default)
- _ImageWidget: convert StatelessWidget → StatefulWidget; move
  generateVideoThumbnail() to initState/didUpdateWidget so it is not
  re-triggered on every rebuild
- _tryLoad: add `if (!mounted) return` guard at entry to prevent
  re-entrant calls after dispose; guard setState after await with
  `if (mounted)`; move state mutations inside setState closures
- chat.dart: call MxcImageCacheManager.instance.clear() in dispose()
  alongside imageCache.clear() so raw compressed bytes are also evicted
  when leaving a room
Copy link
Copy Markdown

@codescene-delta-analysis codescene-delta-analysis bot left a comment

Choose a reason for hiding this comment

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

Gates Passed
3 Quality Gates Passed

See analysis details in CodeScene

Quality Gate Profile: The Bare Minimum
Install CodeScene MCP: safeguard and uplift AI-generated code. Catch issues early with our IDE extension and CLI tool.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 3, 2026

This PR has been deployed to https://linagora.github.io/twake-on-matrix/2987

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.

1 participant