Reputation: 3625
I am testing the dynamic change of the src
property of an <iframe>
inside a Vue
template. In the test I am changing the src once a second. Within a couple of minutes my available memory was used by 88 % , eventually the computer froze in the end. I performed this test on a Windows 10 Machine with 32 GB Memory and Firefox Browser.
However, I first noticed memory problems using a similiar approach on a Raspberry Pi 4 (4GB) using chromium-browser. I continuesly switched through multiple vue components (like slides). Some of them have iframes
in them as well. Just like in the test from above, the memory leaked (not as fast but within couple of days), and the chromium-browser tab crashed, showing the he's dead jim smiley face.
Here is the code from the test:
<template>
<div id="app">
<iframe :src="src" />
{{ count }}
{{ src }}
</div>
</template>
<script>
export default {
data() {
return {
src : "",
source : [
"https://example.com/embeddedcontent/1",
"https://example.com/embeddedcontent/2",
"https://example.com/embeddedcontent/3",
"https://example.com/embeddedcontent/4"
],
count : 0,
interval : null
}
},
mounted() {
const interval = setInterval(() => {
this.src = this.source[ this.count % this.source.length ];
this.count = this.count + 1
}, 2000);
this.interval = interval;
},
beforeDestroy() {
clearInterval(this.interval);
}
}
</script>
Win10/Firefox
, Raspbian/chromium-browser
)src
property can be set to any URL.So far I only thought about refreshing the browser tab every couple of minutes. This would be kindof a hacky solution, since it is not tackling the source of the problem. Are there any alternatives to using iframes
when I want to show another websites content inside my Vue App ? Is there are way to just clean up the whole iframe
without anything being left behind ?
I now tried Edge Browser as well, same result (increasing memory overtime). I also tried Firefox Private mode, had only a very low impact (increasing memory but a bit slower). Compared production and development build of the vue example, no difference. I also tried a vanilla electron app with the following code (no vue):
let interval = null;
let sources = [
"https://hurtigruten.panomax.com/ms-roald-amundsen",
"https://hurtigruten.panomax.com/ms-fridtjof-nansen",
"https://rosenalp.panomax.com/",
"https://alpbach.panomax.com/galtenberg",
];
let index = 0;
let count = 0;
function startTheInterval() {
interval = setInterval(() => {
index = count % sources.length;
count = count + 1;
document.getElementById('monitor').src = sources[index];
},2000);
}
function clearTheInterval() {
clearInterval(interval);
}
startTheInterval();
Same result, increasing memory fast .
Upvotes: 5
Views: 2188
Reputation: 37853
First, some theory about how iframe
works in the browser - Detached window memory leaks
When you trying to debug memory leaks, always use a "incognito mode" - mode when browser is not using any extensions. Extensions may keep references to a HTML loaded into a iframe
and keep that data alive. When I was profiling your example in Chrome, just switching to incognito mode resulted into huge decrease of memory allocation and retention...
Do not use Vue CLI/Webpack dev mode to debug memory leaks. Webpack's hot module reloading (HMR) can affect what is kept in memory. Always use production build for that...
Be aware that JS runtimes (V8 in this case) collect some metadata about the code being executed and keep it in the JS heap. What looks like a memory leak may be just JS virtual machine metadata...
UPDATE:
I'v run some tests using your example (with 1s interval instead of 2s) on my dev machine (Ryzen 5 3600, 32G of RAM, Win 10 x64) - production build served by serve-handler
loaded into Firefox Developer edition v86.0b9 (64-bit) Private window (so no extensions of any kind)
First with Dev Tools open and Memory profiling turned on (with Record call stacks
option turned ON). Recorded one snapshot at the beginning and one more after around 40 minutes. Comparing those snapshots didn't show any JS heap allocation increase. Browser's Private Bytes (using Sysinternals Process Explorer) showed around 60MB increase but that memory was cleared the moment i'v closed the Dev Tools so it's safe to say it was memory used by Dev Tools
Same example, now without opening Dev Tools - running for 40 minutes. Again without any memory increase...
So my conclusion is there is no memory leak tied to an iframe
or Vue itself. If you really see something as dramatic as "Within a couple of minutes my available memory was used by 88 %" you should check your own system, especially the extensions installed in the browser....
Upvotes: 3