解讀生產環境爲什麼避免使用console.log

console.log:向web開發控制檯打印一條消息,經常使用來在開發時調試分析。有時在開發時,須要打印一些對象信息,但發佈時卻忘記去掉console.log語句,這可能形成內存泄露。html

在傳遞給console.log的對象是不能被垃圾回收 ♻️,由於在代碼運行以後須要在開發工具能查看對象信息。因此最好不要在生產環境中console.log任何對象。web

實例------>demos/log.html瀏覽器

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Leaker</title>
</head>

<body>
  <input type="button" value="click">
  <script>
    !function () {
      function Leaker() {
        this.init();
      };
      Leaker.prototype = {
        init: function () {
          this.name = (Array(100000)).join('*');
          console.log("Leaking an object %o: %o", (new Date()), this);// this對象不能被回收
        },

        destroy: function () {
          // do something....
        }
      };
      document.querySelector('input').addEventListener('click', function () {
        new Leaker();
      }, false);
    }()
  </script>
</body>

</html>

這裏結合Chrome的Devtools–>Performance作一些分析,操做步驟以下:工具

⚠️注:最好在隱藏窗口中進行分析工做,避免瀏覽器插件影響分析結果性能

  1. 開啓【Performance】項的記錄
  2. 執行一次CG,建立基準參考線
  3. 連續單擊【click】按鈕三次,新建三個Leaker對象
  4. 執行一次CG
  5. 中止記錄

clipboard.png

能夠看出【JS Heap】線最後沒有降回到基準參考線的位置,顯然存在沒有被回收的內存。若是將代碼修改成:開發工具

!function () {
  function Leaker() {
    this.init();
  };
  Leaker.prototype = {
    init: function () {
      this.name = (Array(100000)).join('*');
    },

    destroy: function () {
      // do something....
    }
  };
  document.querySelector('input').addEventListener('click', function () {
    new Leaker();
  }, false);
}()

去掉console.log("Leaking an object %o: %o", (new Date()), this);語句。重複上述的操做步驟,分析結果以下:ui

clipboard.png

從對比分析結果可知,console.log打印的對象是不會被垃圾回收器回收的。所以最好不要在頁面中console.log任何大對象,這樣可能會影響頁面的總體性能,特別在生產環境中。除了console.log外,另外還有console.dir、console.error、console.warn等都存在相似的問題,這些細節須要特別的關注。this

相關文章
相關標籤/搜索