定时器触发的angularJS性能问题

Posted

技术标签:

【中文标题】定时器触发的angularJS性能问题【英文标题】:angularJS performance issue with timer fired 【发布时间】:2015-09-17 11:18:30 【问题描述】:

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

我已经使用 chrome 开发者工具根据时间线给我的内容提出了以下内容:

如您所见,计时器在渲染发生之前被触发了很长时间。当用户多次执行此操作(关闭弹出窗口并再次重新打开)时,此时间会越来越长。除非他转到其他页面并返回或刷新页面。所以....我怎样才能销毁所有以前的计时器或必须做些什么来收集垃圾。或者是其他必须做的事情。

【问题讨论】:

【参考方案1】:

您应该将按钮调用的函数包装在 debounce 函数中。请参阅下面的功能。这将确保无论何时用户单击按钮,最后一个操作都会被取消。

关于性能,请确保弹出内容在用户关闭时从 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);
  ;
;

【讨论】:

【参考方案2】:

我建议使用 $timeout 而不是 setTimeout because of these reasons。

如本例所示,当 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的示例

【讨论】:

以上是关于定时器触发的angularJS性能问题的主要内容,如果未能解决你的问题,请参考以下文章

细说React组件性能优化

细说React组件性能优化

细说React组件性能优化

细说React组件性能优化

细说React组件性能优化

细说React组件性能优化