Skip to content

fix: Patch Memory Leaks#1261

Merged
spuppo-mux merged 12 commits intomuxinc:mainfrom
spuppo-mux:fix/patch_memory_leaks
Feb 19, 2026
Merged

fix: Patch Memory Leaks#1261
spuppo-mux merged 12 commits intomuxinc:mainfrom
spuppo-mux:fix/patch_memory_leaks

Conversation

@spuppo-mux
Copy link
Contributor

@spuppo-mux spuppo-mux commented Jan 16, 2026

This PR addresses some memory leak issues across many of media-chrome components. Relates to muxinc/elements#1235

The main idea in these changes is to clean references on component disconnect. It includes changes like removing added event listeners, disconnecting MutationObservers, and making sure we keep reference to the functions passed as callbacks to these types of objects.

It also includes some minor fixes like: adding typing; moving some logic from the components constructor to connectedCallback, for example adding event listeners or reinitializing stuff that is removed on disconnect; adding guards so that listeners are not added more than once.

Testing

To test this I added the examples/vanilla/memory-leak-tester.html file which allows mounting and unmounting a <media-controller> element.

The process consisted on mounting and unmounting the component and taking a heap snapshot to verify no leaks are present. To track memory leaks you can check the element's retainer tree to try and find who is holding the reference. It's highly recommended to use a non minified version of the code when testing.

Some extra details

  1. Hanging <video> tag
    When debugging media chrome, even if it's not specifically a component being leaked, we may find a Detached video tag
image

It should be an empty <video> tag, which relates to testMediaEl used in src/js/utils/platform-tests.ts as we can see from it's retainers. It is purposefully maintained in memory to not create several ones when checking some browser compatibilities.

Meaning that a "clean" heap snapshot looks like this:
image

  1. Another video tag is held by a console warning about aria-hidden, which in turn holds the media controller:
Blocked aria-hidden on an element because its descendant retained focus. The focus must not be hidden from assistive technology users. Avoid using aria-hidden on a focused element or its ancestor. Consider using the inert attribute instead, which will also prevent focus. For more details, see the aria-hidden section of the WAI-ARIA specification at https://w3c.github.io/aria/#aria-hidden.
Element with focus: <video slot=media>
Ancestor with aria-hidden: 
<video slot=media> 
<video slot=​"media" playsinline src=​"https:​/​/​stream.mux.com/​A3VXy02VoUinw01pwyomEO3bHnG4P32xzV7u1j1FSzjNg/​high.mp4" aria-hidden=​"true" tabindex=​"-1">​</video>

To remove this I added the inert attribute on media-container.ts:414, but this makes the element non clickable, which may not be desired. Alternatively, we can remove the aria-hidden attribute, but I understand this was added to address accessibility issues in a previous PR. muxinc/elements#1040
On media-controller:510 (mediaSetCallback), we set media tabIndex to -1, meaning it's not keyboard accessible.

  1. Also, when debugging, sometimes Chrome will cache some elements (holding reference to the whole tree of components), which looks like a memory leak. Generally, if <symbol Window#DocumentCachedAccessor>inWindow (global*) / appears as one of the first retainers, it means that this is happening.
image One way to check this is not actually a leak is to mount the component again, play the video, and unmount it. Now on another heap snapshot we should no longer see these elements.

@spuppo-mux spuppo-mux requested review from a team and heff as code owners January 16, 2026 20:25
@vercel
Copy link

vercel bot commented Jan 16, 2026

@spuppo-mux is attempting to deploy a commit to the Mux Team on Vercel.

A member of the Team first needs to authorize it.

@snyk-io
Copy link

snyk-io bot commented Jan 16, 2026

Snyk checks have passed. No issues have been found so far.

Status Scanner Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues
Licenses 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@codecov
Copy link

codecov bot commented Jan 16, 2026

Codecov Report

❌ Patch coverage is 79.72973% with 30 lines in your changes missing coverage. Please review.
✅ Project coverage is 73.72%. Comparing base (3ea80df) to head (53a990f).
⚠️ Report is 277 commits behind head on main.

Files with missing lines Patch % Lines
src/js/media-volume-range.ts 11.76% 15 Missing ⚠️
src/js/media-time-display.ts 33.33% 8 Missing ⚠️
src/js/media-chrome-range.ts 25.00% 3 Missing ⚠️
src/js/media-preview-thumbnail.ts 0.00% 2 Missing ⚠️
src/js/media-gesture-receiver.ts 91.66% 0 Missing and 1 partial ⚠️
src/js/media-store/state-mediator.ts 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1261      +/-   ##
==========================================
- Coverage   78.55%   73.72%   -4.84%     
==========================================
  Files          59       56       -3     
  Lines       11080    13821    +2741     
  Branches        0      784     +784     
==========================================
+ Hits         8704    10189    +1485     
- Misses       2376     3598    +1222     
- Partials        0       34      +34     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@spuppo-mux spuppo-mux linked an issue Jan 20, 2026 that may be closed by this pull request
1 task
@vercel
Copy link

vercel bot commented Jan 27, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
media-chrome Ready Ready Preview, Comment Jan 27, 2026 7:35pm
media-chrome-docs Ready Ready Preview, Comment Jan 27, 2026 7:35pm

Request Review

Copy link
Collaborator

@luwes luwes left a comment

Choose a reason for hiding this comment

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

Thanks for all the fixes.

Are you sure these are all necessary?
Could you try to make the least amount of changes that are needed to solve the problem, could be that it's needed. Just double checking.

@spuppo-mux spuppo-mux requested a review from luwes February 11, 2026 20:03
Copy link
Collaborator

@luwes luwes left a comment

Choose a reason for hiding this comment

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

LGTM thank you!

@spuppo-mux spuppo-mux merged commit d0b6922 into muxinc:main Feb 19, 2026
6 of 10 checks passed
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.

Bug: Mux Player memory not released when unmounted

2 participants