绑定JSON数据时HTML表格的渲染缓慢 [英] Slow rendering of HTML table when binding JSON data

查看:239
本文介绍了绑定JSON数据时HTML表格的渲染缓慢的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在此处使用带有webapi的angularjs(1.3).

我有一个用户可以在其中上传excel文件的UI.我的api读取excel文件,并将行数据以JSON的形式返回给UI.

然后,UI读取JSON并将其绑定回UI表.

此UI表的行和列是动态生成的,并且不是固定的,因此我正在HTML中使用contenteditable,因为用户可以添加更多行.

我可以从JSON精细中读取并填充保存这些JSON值的数组.问题在于渲染时,屏幕被冻结并且需要时间来渲染所有数据. 我目前绑定约800行,并且屏幕冻结,并且大约需要10-15秒或更长时间来填充UI表.我将拥有更多数据,因此正在寻找解决方案.

我尝试调试,可以看到从API返回数据并从API读取JSON没有问题.填充数组时也没有问题. 一旦阵列填充,多数民众赞成在问题来临时. UI冻结,需要花费一些时间来呈现这些数据.

我不确定这里发生了什么或为什么要花这么长时间才能渲染.以下是一些相关示例代码:

//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中添加了注释,以显示什么方法可以做什么.

如果有人可以帮助我解决此问题,我们将不胜感激.

解决方案

以下是一些性能统计信息:

具有可编辑的内容(约4000个摘要调用)= 1.800ms-> http://prntscr.com/lweugn

没有可编辑的内容(约4个摘要调用)= 1.300ms-> http://prntscr.com/lweusn

分页仅显示前50个结果= 0.200ms-> 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

Using angularjs (1.3) with webapi here.

I have UI where the user can upload a excel file. My api reads the excel file and returns rows data back to the UI in JSON.

The UI then reads the JSON and binds it back the UI table.

The rows and columns of this UI table are dynamically generated and are not fixed, because of which I am using contenteditable in HTML as the user can add more rows.

I can read from the the JSON fine and populate the array that holds these json values. The issue is while rendering, the screen is frozen and takes time to render all the data. I am currently binding about 800 rows and the screen freezes and takes about 10-15 seconds or more to fill up the UI table. I would be having lot more data so looking for a solution for this.

I tried to debug and can see that there is no issue getting data back from the API, and reading JSON from the API. There is also no issue while populating the array. Once the array populates thats when the issue comes. The UI freezes and takes time to render this data.

I am not sure whats going on here or why it takes so time to render. Below is some sample relevant code:

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

Below is the relevant code for the UI:

<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>

I have created the below JSFiddle to show my example and issue I am facing.

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

I have also added comments in my jsfiddle for showing what method does what.

Would appreciate if anyone can help my resovling this issue.

解决方案

Here are some performance stats:

with contenteditable (~4000 digest calls) = 1.800ms -> http://prntscr.com/lweugn

without contenteditable (~4 digest calls) = 1.300ms -> http://prntscr.com/lweusn

with pagination just showing the first 50 results = 0.200ms -> http://prntscr.com/lwev09

You loose the most performance because of the DOM changes obviously. But keep in mind that the number and duration of digest cycles is key for good performance. Especially when you have a huge amount of watchers. Here is a Direct comparison: http://prntscr.com/lwf1nn As you can see the digest loop is burning 30% of your performance overall but is not the reason for your frame drop. The frame drop is mostly caused of the DOM changes. Drawing such a big table takes some time.

Further the table starts rendering when your REST call is finished. This call takes in my case roughly additional 1.700ms. So it takes nearly 3.500ms from start until rendered results. Even with pagination 1.900ms.

I would recommend a pagination with search but you can try to increase the performance anyway.

Helpful links would be:

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

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

这篇关于绑定JSON数据时HTML表格的渲染缓慢的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆