You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I've used Howler in production with Vue and we've seen a lot of our audio players that have been streaming for a long time use significant amounts of RAM. So I went down the rabbit hole and found out it was Howler.
I wanted to make sure the leaks are not caused by anything we have internally, so I went ahead and created a small HTML file to reproduce the behaviour of creating new Howl instances and unloading them (just the bare minimum) and it turns out the results are exactly the same.
Even if I inspect the heap manually, I can clearly see the retained size growing with each new Howl. Turns out, .unload() never really releases it.
So I actually implemented a barebones .changeSong function to replace my current howl and avoid creating new instances. MemLab is still reporting leaks BUT the retained size never changes with 10, 100 or 200 playthroughs whereas it does bubble up with my previous example (which, as far as I understand, is the recommended approach for adding more songs programatically, e.g. user adds more songs into playlist). Here's the MemLab result with .changeSong in place:
TL;DR .unload() doesn't release the instance from memory, MemLab and Chrome snapshots show a continuous increase and report memory leaks.
It's a long known issue with Howler using Web Audio API. But everything is fine with html5 option enabled. Maybe some day someone will propose a patch to fix this.
The Problem
I've used Howler in production with Vue and we've seen a lot of our audio players that have been streaming for a long time use significant amounts of RAM. So I went down the rabbit hole and found out it was Howler.
I wanted to make sure the leaks are not caused by anything we have internally, so I went ahead and created a small HTML file to reproduce the behaviour of creating new Howl instances and unloading them (just the bare minimum) and it turns out the results are exactly the same.
Even if I inspect the heap manually, I can clearly see the retained size growing with each new Howl. Turns out,
.unload()
never really releases it.So I actually implemented a barebones .changeSong function to replace my current howl and avoid creating new instances. MemLab is still reporting leaks BUT the retained size never changes with 10, 100 or 200 playthroughs whereas it does bubble up with my previous example (which, as far as I understand, is the recommended approach for adding more songs programatically, e.g. user adds more songs into playlist). Here's the MemLab result with .changeSong in place:
TL;DR
.unload()
doesn't release the instance from memory, MemLab and Chrome snapshots show a continuous increase and report memory leaks.Reproducible Example
Make sure to run this locally, save as index.html then do
npx http-server .
:https://codesandbox.io/p/sandbox/vibrant-cartwright-53xwxk?layout=%257B%2522sidebarPanel%2522%253A%2522EXPLORER%2522%252C%2522rootPanelGroup%2522%253A%257B%2522direction%2522%253A%2522horizontal%2522%252C%2522contentType%2522%253A%2522UNKNOWN%2522%252C%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522id%2522%253A%2522ROOT_LAYOUT%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522contentType%2522%253A%2522UNKNOWN%2522%252C%2522direction%2522%253A%2522vertical%2522%252C%2522id%2522%253A%2522clyppi17d00063b6jolxpla5g%2522%252C%2522sizes%2522%253A%255B100%252C0%255D%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522contentType%2522%253A%2522EDITOR%2522%252C%2522direction%2522%253A%2522horizontal%2522%252C%2522id%2522%253A%2522EDITOR%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL%2522%252C%2522contentType%2522%253A%2522EDITOR%2522%252C%2522id%2522%253A%2522clyppi17d00023b6jy5ey8op2%2522%257D%255D%257D%252C%257B%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522contentType%2522%253A%2522SHELLS%2522%252C%2522direction%2522%253A%2522horizontal%2522%252C%2522id%2522%253A%2522SHELLS%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL%2522%252C%2522contentType%2522%253A%2522SHELLS%2522%252C%2522id%2522%253A%2522clyppi17d00033b6jrr1r8m4p%2522%257D%255D%252C%2522sizes%2522%253A%255B100%255D%257D%255D%257D%252C%257B%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522contentType%2522%253A%2522DEVTOOLS%2522%252C%2522direction%2522%253A%2522vertical%2522%252C%2522id%2522%253A%2522DEVTOOLS%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL%2522%252C%2522contentType%2522%253A%2522DEVTOOLS%2522%252C%2522id%2522%253A%2522clyppi17d00053b6jxgl2gq1z%2522%257D%255D%252C%2522sizes%2522%253A%255B100%255D%257D%255D%252C%2522sizes%2522%253A%255B50%252C50%255D%257D%252C%2522tabbedPanels%2522%253A%257B%2522clyppi17d00023b6jy5ey8op2%2522%253A%257B%2522tabs%2522%253A%255B%257B%2522id%2522%253A%2522clyppi17c00013b6jufui98nr%2522%252C%2522mode%2522%253A%2522permanent%2522%252C%2522type%2522%253A%2522FILE%2522%252C%2522filepath%2522%253A%2522%252Fsrc%252Findex.html%2522%252C%2522state%2522%253A%2522IDLE%2522%257D%255D%252C%2522id%2522%253A%2522clyppi17d00023b6jy5ey8op2%2522%252C%2522activeTabId%2522%253A%2522clyppi17c00013b6jufui98nr%2522%257D%252C%2522clyppi17d00053b6jxgl2gq1z%2522%253A%257B%2522tabs%2522%253A%255B%257B%2522id%2522%253A%2522clyppi17d00043b6j2w0il0wj%2522%252C%2522mode%2522%253A%2522permanent%2522%252C%2522type%2522%253A%2522UNASSIGNED_PORT%2522%252C%2522port%2522%253A0%252C%2522path%2522%253A%2522%252F%2522%257D%255D%252C%2522id%2522%253A%2522clyppi17d00053b6jxgl2gq1z%2522%252C%2522activeTabId%2522%253A%2522clyppi17d00043b6j2w0il0wj%2522%257D%252C%2522clyppi17d00033b6jrr1r8m4p%2522%253A%257B%2522tabs%2522%253A%255B%255D%252C%2522id%2522%253A%2522clyppi17d00033b6jrr1r8m4p%2522%257D%257D%252C%2522showDevtools%2522%253Atrue%252C%2522showShells%2522%253Afalse%252C%2522showSidebar%2522%253Atrue%252C%2522sidebarPanelSize%2522%253A15%257D
Reproduction Steps
Possible Solution
I assume fix .unload() so it properly releases the previous instance.
Context
/
Howler.js Version
v2.2.4
Affected Browser(s)/Versiuon(s)
Chrome 125
The text was updated successfully, but these errors were encountered: