包含js代码的dom元素从页面上消失后发生了什么
最近遇到了一个问题:有一个数据看板的页面运行了 n 天后突然页面崩溃了,爆出了 out of memory 的错误。页面不复杂,几个图表定时更新数据,没明白为什么长时间运行后会 out of memory。
在每次请求后使用
console.log(window.performance.memory);
打印出页面的内存占用情况,然后就发现了问题,每次请求完成过后,占用的内存一直递增,长时间运行后 out of memory 就不奇怪了。
简单的写个 demo,看下包含 js 代码的 dom 元素从页面上消失后发生了什么?js 代码中的变量、函数、定时器是否还可以使用?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div id="main">
<div>test</div>
<script>
let a = 1;
function test() {
console.log("dom show");
}
var timer = setInterval(function () {
a += 1;
console.log(a);
}, 2000);
</script>
</div>
</body>
<script>
test();
setTimeout(() => {
document.querySelector("#main").remove();
console.log("dom 消失");
a = a + 6;
console.log(a);
}, 3000);
</script>
</html>
可以看出dom消失后 其中包含的 js 变量、函数、定时器依然可以继续使用。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div id="main">
<div>test</div>
<script>
let a = 1;
function test() {
console.log("dom show");
}
var timer = setInterval(function () {
a += 1;
console.log(a);
}, 2000);
function func() {
console.log("func");
a = null;
clearInterval(timer);
test = null;
func = null;
}
</script>
</div>
</body>
<script>
test();
setTimeout(() => {
document.querySelector("#main").remove();
console.log("dom 消失");
a = a + 6;
console.log(a);
}, 3000);
setTimeout(() => {
func();
}, 5000);
</script>
</html>
试着在 dom 消失后清除其中定义的变量、函数、定时器

在数据看板中加入清除之前变量、函数、定时器、事件的逻辑后,请求后页面内存占用的递增缓了很多,效用明显,然而虽然递增缓慢,但是整体的趋势还是在递增的,最终终会有 out of memory 的一天。其本质原因还是页面的架构问题:定时请求的每次请求都是返回一个包含 div 元素、代码、数据的页面,新返回的代码和数据会不断开辟新的内存空间,时间久了内存肯定就满了,如果只是返回数据,用新数据取代旧数据而不会不断开辟新的内存空间,应该就不会出现out of memory 了。然这种改动就太大了,尽量不要去动老代码。
同事提到了一个简单的办法:定时刷新页面,很简单有效的解决了这个问题
<meta http-equiv="refresh" content="360000">
浙公网安备 33010602011771号