Оптимизировать директиву ng-bind в angularjs - PullRequest
0 голосов
/ 09 апреля 2019

В моем угловом js-приложении у меня есть массив объектов $scope.time, которые содержат имя, текущее время и другое определенное время в миллисекундах.Во внешнем интерфейсе я использую ng-bind, чтобы вычислить разницу между этими двумя значениями времени и отобразить ее в формате H: m: s.Пожалуйста, запустите код ниже.

var app = angular.module('angularapp', []);
app.filter("msTotime", function() {
  return function(timee,started,ended) {
    var startDate = new Date(started);
    var endDate = new Date(ended);
    var milisecondsDiff = endDate - startDate;
    var final = Math.floor(milisecondsDiff/(1000*60*60)).toLocaleString(undefined, {minimumIntegerDigits: 2}) + ":" + (Math.floor(milisecondsDiff/(1000*60))%60).toLocaleString(undefined, {minimumIntegerDigits: 2})  + ":" + (Math.floor(milisecondsDiff/1000)%60).toLocaleString(undefined, {minimumIntegerDigits: 2}) ;
    var defaulttime = '00:00:00';
    if(final == '-01:-01:-01'){
    return  defaulttime;
    }
    else {
    return final;
  }
}
});
app.controller('list', function($scope,$window) {
$scope.time = [{"game":"Halo","now":1554805270181,"time":1554794475267},
{"game":"CODuty","now":1554805270181,"time":1554802957031},
{"game":"WOF","now":1554805270181,"time":1554732154093},
{"game":"WarCraft","now":1554805270181,"time":1554803456875},
{"game":"POP","now":1554805270181,"time":1554803456275},
{"game":"RedBulls","now":1554805270181,"time":1554800620012},
{"game":"Eragon","now":1554805270181,"time":1554433320072}];
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.10/angular.min.js"></script>
<div ng-app="angularapp">
<div ng-controller="list" >
<div ng-repeat="timer in time">
<h5>{{timer.game}}</h5><hr>
Milliseconds to H:M:S for  {{timer.game}} <p style="display:inline-block" ng-bind="realtime | msTotime:timer.time:timer.now"></p><br>
</div>
</div>
</div>

Массив $scope.time является динамическим, так как я получаю эти данные из API (я определил их здесь жестко для демонстрации).Приведенный выше код работает гладко, когда у меня есть несколько объектов в массиве $scope.time.Но когда появляются тысячи объектов, мой браузер начинает зависать, поскольку фильтр msTotime продолжает вычислять разницу между миллисекундами, преобразовывает ее в H:m:s и привязывает ее к внешнему интерфейсу.

Теперь проблема заключается в том, чточто мой браузер потребляет 40 процентов процессорного времени при наличии 1000 объектов.Я полагаю, что это не проблема с ng-repeat, поскольку, когда я прокомментировал <p style="display:inline-block" ng-bind="realtime | msTotime:timer.time:timer.now">, загрузка процессора составляла всего 5 процентов для более чем 1000 объектов.

Есть ли способ оптимизировать директиву ng-bind здесь или выполнить вычисление времени другим способом, чтобы вычисления, выполняемые фильтром msTotime, не потребляли так много ЦП.

1 Ответ

1 голос
/ 11 апреля 2019

Я бы предложил использовать библиотеку lodash https://lodash.com для добавления разницы во времени в каждом объекте вместо использования directive для этого. поэтому каждый раз, когда вы получаете данные из запроса, используйте _.each для выполнения одной и той же операции и вставьте переменную realtime.

var app = angular.module('angularapp', []);

app.controller('list', function($scope,$window) {

  $scope.time = [
    {"game":"Halo","now":1554805270181,"time":1554794475267},
    {"game":"CODuty","now":1554805270181,"time":1554802957031},
    {"game":"WOF","now":1554805270181,"time":1554732154093},
    {"game":"WarCraft","now":1554805270181,"time":1554803456875},
    {"game":"POP","now":1554805270181,"time":1554803456275},
    {"game":"RedBulls","now":1554805270181,"time":1554800620012},
    {"game":"Eragon","now":1554805270181,"time":1554433320072}
  ];

  _.each($scope.time, function(obj, index){   
      var startDate = new Date(obj.time);
      var endDate = new Date(obj.now);
      var milisecondsDiff = endDate - startDate;
      var final = Math.floor(milisecondsDiff / (1000 * 60 * 60)).toLocaleString(undefined, {
        minimumIntegerDigits: 2
      }) + ":" + (Math.floor(milisecondsDiff / (1000 * 60)) % 60).toLocaleString(undefined, {
        minimumIntegerDigits: 2
      }) + ":" + (Math.floor(milisecondsDiff / 1000) % 60).toLocaleString(undefined, {
        minimumIntegerDigits: 2
      });
      var defaulttime = '00:00:00';
      if (final == '-01:-01:-01') {
        obj.realtime = defaulttime;
      } else {
        obj.realtime = final;
      }
  });
    
  
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.10/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.core.min.js"></script>

<div ng-app="angularapp">
<div ng-controller="list" >
<div ng-repeat="timer in time">
<h5>{{timer.game}}</h5><hr/>
Milliseconds to H:M:S for {{timer.game}} <p style="display:inline-block;">{{timer.realtime}}</p><br>
</div>
</div>
</div>
...