包含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">

 

posted @ 2023-06-16 15:36  carol2014  阅读(27)  评论(0编辑  收藏  举报