简体   繁体   中英

angularJS performance issue with timer fired

I am building a pretty huge angular app, My problem is the memory leaks resulting in page freeze. on clicking a button, my app opens up a popup,(with help of custom directive) the content of this popup is dynamically appended and the popup is called with $http from the local file.It works fine.

I have used chrome developer tools to come up with the following as per what timeline gave me:

As you can see, the timer is fired for a long time before the render happens. and the time of this gets more and more when the user do it multiple times(closing popup and reopen again). Unless he goes to some other page and come back or refresh the page.So.... How can I destroy all the previous timers or what has to be done to collect the garbage.Or is it something else that has to be done. 在此输入图像描述

You should wrap the function called by the button in a debounce function. See function below. This will make sure that whenever the user click on the button the last action is cancelled.

In regards to performance make sure that the popup content is removed from the dom when it is closed by the user.

Sourced from: 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);
  };
};

I'd recommend using $timeout over setTimeout because of these reasons .

A possible solution to your memoryleak is by cancelling timers when Angular removes the element from the DOM as shown in this example:

 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 );
                    }

example from Ben Nadel

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM