定时器触发的angularJS性能问题

时间:2015-06-30 15:09:17

标签: javascript angularjs settimeout developer-tools angular-directive

我正在构建一个非常巨大的角度应用程序,我的问题是内存泄漏导致页面冻结。 单击一个按钮,我的应用程序打开一个弹出窗口,(在自定义指令的帮助下)动态附加此弹出窗口的内容,并使用本地文件中的$ http调用弹出窗口。它工作正常。

我已经使用chrome开发人员工具根据时间轴给出了以下内容:

正如您所看到的,在渲染发生之前,计时器会被激活很长时间。当用户多次执行此操作时,此时间越来越多(关闭弹出窗口并再次重新打开)。除非他去其他页面然后回来或刷新页面。所以....我怎么能摧毁所有以前的计时器或者必须采取什么措施来收集垃圾。或者它是否需要做其他事情。 enter image description here

2 个答案:

答案 0 :(得分:1)

你应该在去抖动功能中包含按钮调用的功能。见下面的功能。这将确保每当用户单击按钮时,最后一个操作被取消。

关于性能,请确保在用户关闭时从dom中删除弹出内容。

来自:https://davidwalsh.name/javascript-debounce-function

function debounce(func, wait, immediate) {
  var timeout;
  return function() {
    var context = this, args = arguments;
    var later = function() {
      timeout = null;
      if (!immediate) func.apply(context, args);
    };
    var callNow = immediate && !timeout;
    clearTimeout(timeout);
    timeout = setTimeout(later, wait);
    if (callNow) func.apply(context, args);
  };
};

答案 1 :(得分:0)

我建议在setTimeout because of these reasons上使用$ timeout。

对memoryleak的一种可能解决方案是在Angular从DOM中删除元素时取消定时器,如下例所示:

 var timer = $timeout(
                    function() {
                        console.log( "Timeout executed", Date.now() );
                    },
                    2000
                );
                // Let's bind to the resolve/reject handlers of
                // the timer promise so that we can make sure our
                // cancel approach is actually working.
                timer.then(
                    function() {
                        console.log( "Timer resolved!", Date.now() );
                    },
                    function() {
                        console.log( "Timer rejected!", Date.now() );
                    }
                );
                // When the DOM element is removed from the page,
                // AngularJS will trigger the $destroy event on
                // the scope. This gives us a chance to cancel any
                // pending timer that we may have.
                $scope.$on(
                    "$destroy",
                    function( event ) {
                        $timeout.cancel( timer );
                    }

来自Ben Nadel

的示例