Медленное отображение таблицы HTML при привязке данных JSON - PullRequest
0 голосов
/ 17 декабря 2018

Использование angularjs (1.3) с webapi здесь.

У меня есть пользовательский интерфейс, где пользователь может загрузить файл Excel.Мой API читает файл Excel и возвращает данные строк обратно в пользовательский интерфейс в формате JSON.

Затем пользовательский интерфейс читает JSON и связывает его с таблицей пользовательского интерфейса.

Строки и столбцы этого пользовательского интерфейсатаблицы генерируются динамически и не являются фиксированными, из-за чего я использую contenteditable в HTML, поскольку пользователь может добавлять больше строк.

Я могу читать из штрафа JSON и заполнять массив, содержащий эти значения json.Проблема заключается в том, что во время рендеринга экран завис и требует времени для отображения всех данных.В настоящее время я связываю около 800 строк, и экран зависает, и на заполнение таблицы пользовательского интерфейса уходит около 10-15 секунд или больше.У меня было бы намного больше данных, поэтому я искал решение для этого.

Я попытался отладить и вижу, что нет проблем с возвратом данных из API и чтением JSON из API.Также нет проблем при заполнении массива.Как только массив заполняется, вот когда возникает проблема.Интерфейс пользователя зависает и требует времени для рендеринга этих данных.

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

//Read json from the API

$http.get('https://api.myjson.com/bins/d1ugw').success(function(data) {
if (data.length > 0) {   

  $scope.setJson = data;
  $scope.initializeTable(true);
  var columns = $scope.targetTable.columns;

  //These are the 3 columns of the Table but can vary dynamically(currently just hardcoding it)
  var refColName = "state, month , year";

  //Push the columns to the table array
  var colArray = refColName.split(',');
  for (var i = 0; i < colArray.length; i++) {
    $scope.targetTable.columns.push({
      id: columns.length,
      refColName: refColName.split(',')[i]
    });
  }

  //Read the values from the json
  var idValues = $scope.getTableValues($scope.setJson, 'id');
  var commentValues = $scope.getTableValues($scope.setJson, 'comment');
  var rowValues = $scope.getTableValues($scope.setJson, 'refcol');
  var setIdValues = $scope.getTableValues($scope.setJson, 'sid');

  //Push the data back to the table array.
  $scope.pushRowData($scope.targetTable, rowValues, commentValues, idValues, setIdValues);
  //Till the above steps everything happens quickly and I can see $scope.targetTable being populated with my json. 
  //But after the above step the screen just freezes and takes time to show the entire data on the UI table.
 }
  });

Ниже приведен соответствующий код для пользовательского интерфейса:

<tbody>
    <tr ng-repeat="r in targetTable.rows">
      <td class="fixed-width">
        <span>
            <a class="btn-xs" ng-show="row == $index" ng-if="targetTable.rows.length > 1"><i class="fa fa-times-circle" aria-hidden="true"></i></a>
        </span>
        <span contenteditable="true" ng-model="r.tableId" ng-change="addNewRow(r.tableId, r)">{{r.tableId}}</span>
      </td>
      <td class="fixed-width" contenteditable="true" ng-repeat="column in targetTable.columns" ng-model="r[column.id]" ng-change="rowDataChange(r[column.id])"></td>
      <td class="comment-fixed-width" contenteditable="true" ng-model="r.comment" ng-change="rowDataChange(r.comment)"></td>
      <td class="blank fixed-width" colspan="2" ng-model="r[column.id]"></td>
    </tr>
  </tbody>

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

http://jsfiddle.net/aman1981/u1vbeos5/312/

Я также добавил комментарии в jsfiddle, чтобы показать, что и для чего делает метод.

Буду признателен, если кто-нибудь сможет помочь мне решить эту проблему.

Ответы [ 3 ]

0 голосов
/ 17 декабря 2018

Во-первых, я рекомендую вам обновить версию Angular до самой продвинутой версии, если это возможно.Также проверьте версию анимации.Помимо того, что вы подумали об использовании расширенного табличного компонента, такого как ag-grid?, Я могу загрузить 10000 строк без каких-либо проблем с ним.https://www.ag -grid.com /

0 голосов
/ 18 декабря 2018

Вот некоторые характеристики производительности:

с contenteditable (~ 4000 дайджест-вызовов) = 1.800 мс -> http://prntscr.com/lweugn

без contenteditable (~ 4 дайджест-вызовов) = 1.300 мс ->http://prntscr.com/lweusn

с нумерацией страниц, показывающим только первые 50 результатов = 0,200 мс -> http://prntscr.com/lwev09

Очевидно, вы теряете большую часть производительности из-за изменений DOM.Но имейте в виду, что количество и продолжительность циклов дайджеста - это ключ к хорошей производительности.Особенно, когда у вас есть огромное количество наблюдателей.Вот прямое сравнение: http://prntscr.com/lwf1nn Как видите, дайджест-цикл сжигает 30% вашей производительности в целом, но не является причиной падения кадров.Падение кадра в основном вызвано изменениями DOM.Создание такой большой таблицы занимает некоторое время.

Далее таблица начинает рендеринг, когда ваш вызов REST завершен.Этот вызов занимает в моем случае примерно дополнительные 1,700 мс.Таким образом, от начала до получения результатов требуется около 3,500 мсДаже с нумерацией страниц 1.900 мс.

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

Полезные ссылки:

https://stackoverflow.com/a/47347260/8196542

https://www.codeproject.com/Articles/1173869/%2FArticles%2F1173869%2Fng-repeat-performance-degradation-at-case-of-very

0 голосов
/ 17 декабря 2018

Ваш код запускает цикл $ digest снова и снова.Метод «watch» подсчитывает, как часто фактически вызывается цикл $ digest:

var nbDigest = 0;

$scope.$watch(function() {
  nbDigest++;
  console.log(nbDigest);
});

Могу поспорить, что это является причиной ваших проблем с производительностью.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...