Подтвердить что ты не робот

Как избежать утечек памяти с помощью angularjs-nvd3-директив

Я работаю над приложением angularjs, используя директивы angularjs-nvd3 для рендеринга диаграмм.

После проверки с помощью инструментов разработчика Chrome я обнаружил некоторые утечки памяти, связанные с диаграммами. Когда пользователь перемещается по различным представлениям, содержащим диаграммы, память никогда полностью не освобождается.

Я уже делаю очистку на графических контроллерах:

$scope.$on('$destroy', function() {
  d3.select( '#exampleId' ).remove();
  d3.select( '#exampleId2' ).remove();
  ...
});

И в событии routeChange:

myApp.run(function($rootScope, $templateCache) {
  //try to clear unused objects to avoid huge memory usage
  $rootScope.$on('$routeChangeStart', function(event, next, current) {
    if (typeof(current) !== 'undefined'){
      //destroy all d3 svg graph
      d3.selectAll('svg').remove();
      nv.charts = {};
      nv.graphs = [];
      nv.logs = {};
    }
  });
});

Когда я удаляю диаграммы из своего приложения, использование памяти всегда возвращается к исходному значению.

С графиком: with graph Whithout: without

Есть ли другой способ освобождения памяти, сгенерированной этими диаграммами?

jsfiddle, чтобы продемонстрировать эту проблему.

4b9b3361

Ответ 1

Вы можете забыть удалить прослушиватели с изменением размера окна.

angularApp.run(function($rootScope) {
  $rootScope.$on('$routeChangeStart', function(event, next, current) {
    if (typeof(current) !== 'undefined'){
        //destroy d3 stuff 
        window.nv.charts = {};
        window.nv.graphs = [];
        window.nv.logs = {};

        // and remove listeers for onresize. 
        window.onresize = null;
    }
  });
}); 

Также вы можете попробовать удалить весь элемент svg, но это не похоже на лучший способ.

Ответ 2

В github аналогичная проблема: https://github.com/cmaurer/angularjs-nvd3-directives/issues/193

Как я объяснил там, работала лучше:

  $rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams) {
angular.element(document.body.querySelectorAll('.nvd3')).remove();

Это устраняет утечки памяти SVG. Но все же есть некоторые утечки памяти на стороне данных (Array).

Ответ 3

Я рекомендую вам переместить ваш график в свои собственные директивы, которые будут содержать директивы nvd3 на своих шаблонах и слушать каждую директиву для области.

> $destroy также уничтожает элемент на этом событии. Контроллеры должны извлекать данные и назначать их директиве. Возможно, вам захочется прослушать $routeChangeStart в директиве, поэтому очистка будет инкапсулирована на ту часть, которая использует данные. Таким образом, вы избежите дублирования кода.

Я использую эти методы для очистки моих директив, использующих модальные файлы, поэтому у меня нет дубликатов событий или идентификаторов событий.