我在背景上有一个带有ruby-on-rails的Angularjs应用程序。当我发出一个http获取请求时,我恢复它的速度很快,我也没有遇到任何问题。问题出现在我已经获得了我想要的数据并且ng-repeat
需要很长时间才能呈现(或者它可能不是ng-repeat
,我真的不知道)。
下面的一些代码和图片:
我的桌子上有ng-repeat
(我有更多的td' s,但即使只有id很慢):
<md-table-container>
<div ng-if="showSpinner" layout="row" layout-align="center start">
<p></p>
<md-progress-circular ng-if="showSpinner" md-diameter="70"></md-progress-circular>
</div>
<table md-table>
<thead md-head>
<tr md-row>
<th md-column>Situação</th>
<th md-column>Inclusão</th>
<th md-column>Tipo de CTe</th>
<th md-column>Número/Série</th>
<th md-column class="min-width200">Emissor</th>
<th md-column class="text-align-right">Valor</th>
<th md-column>Emissão</th>
<th md-column>
<md-icon md-font-set="md">done_all</md-icon>
<md-tooltip md-direction="top">Recebimento</md-tooltip>
</th>
<th md-column class="max-width5 text-align-center">
<md-icon md-font-set="md">computer</md-icon>
<md-tooltip md-direction="top">SEFAZ</md-tooltip>
</th>
</tr>
</thead>
<tbody>
<tr ng-mouseleave="dataover = 0" ng-mouseover="dataover = document.id" ng-class="{'selected-row': idSelectedDocument === document.id, 'not-selected-row': idSelectedDocument != document.id, 'document_row_active': dataover === document.id, 'document_row': dataover != document.id}" md-row ng-repeat="document in documents track by document.id">
<td>{{document.id}}</td>
<!--Even with only the id it is slow-->
</tr>
</tbody>
</table>
</md-table-container>
<md-table-pagination md-limit="itemsPerPage" md-page="currentPage" md-total="{{totalItems}}" md-label="{page: 'Página:', rowsPerPage: 'Filas por página:', of: 'de'}" md-on-paginate="selectPage(currentPage)" md-page-select></md-table-pagination>
我的Http请求:
$scope.promise = $http.get("/documents.json",
{ "params": {"company_id": company_id} }
).success(
function(data,status,headers,config) {
$scope.documents = data.data;
$scope.totalItems = data.paging;
console.log("HERE");
}).error(
function(data,status,headers,config) {
toastr.error("Error.");
});
如上所述在JS中我有一个console.log(),即使在执行console.log之后,ng-repeat
还没有准备好再花2,3秒。它甚至有时会冻结应用程序。
我安装了Angularjs Batarang以进行更多调试,下面是我的截图,我不认为它影响太大(从我的表angular md-data-table的组件中调用getColumn):
编辑1:在ng-repeat中使我的tds变得缓慢,试图逐个移除以查看它是哪一个但我认为它是所有这些的组合,你们可以帮我试试吗减少花时间?
<td md-cell>
<div ng-mouseover="show_error_states($event, document)">
<span ng-class="{'label-green': isApproved(document.current_state_id),
'label-red': isPending(document.current_state_id),
'label-yellow': isIncluded(document.current_state_id),
'label-orange': isDownloaded(document.current_state_id),
'label-dark-green': isLaunched(document.current_state_id),
'label-gray': isCancelled(document.current_state_id)}">{{document.current_state_title}}{{document.launched_by_erp ? '**' : ''}}</span>
<md-tooltip md-direction="top">
<span>{{document.current_state_view.description}}{{document.launched_by_erp ? ' **Lançado pelo ERP' : ''}}</span>
</md-tooltip>
</div>
</td>
<td md-cell ng-bind="document.received_date | date:'dd/MM/yyyy HH:mm'"></td>
<td md-cell>{{document.dfe_number == null ? '----' : document.dfe_number + '/' + document.dfe_serie}}</td>
<td md-cell>
{{ document.emitter | limitTo: 35 }}{{document.emitter.length > 35 ? '...' : ''}}
<md-tooltip md-direction="top">{{document.emitter + ' - ' + document.emitter_cnpj}}</md-tooltip>
</td>
<td md-cell class="text-align-right" ng-bind="document.dfe_value | currency: 'R$'"></td>
<td md-cell ng-bind="document.dfe_dhemi | date: 'dd/MM/yyyy HH:mm'"></td>
<td md-cell>
<md-icon md-font-set="md">{{document.reception_state == "2" ? 'done' : 'clear'}}</md-icon>
<md-tooltip md-direction="top">{{document.reception_state == "2" ? 'Recebido' : 'Pendente Recebimento'}}</md-tooltip>
</td>
<td md-cell class="text-align-center" ng-mouseover="find_dfe_situation(document)">
<md-icon md-font-set="md">{{hasSuccessSefaz(document.dfe_situation) ? 'done' : ''}}{{hasErrorSefaz(document.dfe_situation) ? 'clear' : ''}}</md-icon>
<md-tooltip ng-if="document.dfe_situation != null" md-direction="top">
<div>
<ul class="without-padding without-bullets">
<li>
<span>{{document.dfe_situation_description}}</span>
</li>
<li>
<span ng-if="document.dfe_situation_date != null">{{' - ' + document.dfe_situation_date | date: 'dd/MM/yyyy HH:mm'}}</span>
</li>
</ul>
</div>
</md-tooltip>
</td>
<td md-cell class="text-align-center" ng-mouseover="find_manifestation(document)">
<md-icon md-font-set="md">{{document.manifestation_state ? 'done' : 'clear'}}</md-icon>
<md-tooltip ng-if="document.manifestation_state == true" md-direction="top">
<div>
<ul class="without-padding without-bullets">
<li>
<span>Descrição da Manifestação:</span>
<span>{{document.manifestation_description}}{{document.manifestation_description == null ? 'Não Possui.' : ''}}</span>
</li>
<li>
<span>Data da Manifestação:</span>
<span>{{document.manifestation_date | date: 'dd/MM/yyyy HH:mm'}}{{document.manifestation_date == null ? 'Não Possui.' : ''}}</span>
</li>
</ul>
</div>
</md-tooltip>
</td>
<td md-cell>
<md-button ng-click="openDanfe(document); setSelectedDocument(document.id)" ng-disabled="document.current_state_id == 17" class="md-raised min-width5">
<md-icon md-font-set="md">find_in_page</md-icon>
<md-tooltip md-direction="top">Danfe</md-tooltip>
</md-button>
<md-menu md-position-mode="target-right target" md-offset="45 35">
<md-button class="min-width5" aria-label="Abrir menu" ng-click="$mdOpenMenu($event); open_documents_menu(document)">
<div md-menu-origin>
<md-icon class="color-blue" md-menu-origin md-font-set="md">settings</md-icon>
</div>
</md-button>
<md-menu-content>
<md-menu-item>
<md-button ng-click="open_nfe_process(document); setSelectedDocument(document.id)" ng-disabled="document.current_state_id == 17 || document.current_state_id == 5 || document.launched_by_erp">
Processo
</md-button>
</md-menu-item>
<md-menu-item>
<md-button ng-click="launch_now(document, $event); setSelectedDocument(document.id)" ng-disabled="document.current_state_id != 20">
Lançar no ERP
</md-button>
</md-menu-item>
<md-menu-item permission only="'admin'">
<md-button ng-click="delete_now_erp(document, $event); setSelectedDocument(document.id)" ng-disabled="document.current_state_id != 21 || document.launched_by_erp">
Excluir no ERP
</md-button>
</md-menu-item>
<md-menu-item>
<md-button ng-click="files(document, $event); setSelectedDocument(document.id)">
Gerenciar Anexos
</md-button>
</md-menu-item>
<md-menu-item>
<md-button ng-click="manifest(document, $event); setSelectedDocument(document.id)">
Manifestar
</md-button>
</md-menu-item>
<md-menu-item>
<md-button ng-click="events(document, $event); setSelectedDocument(document.id)">
Ocorrências
</md-button>
</md-menu-item>
<md-menu-item>
<md-button ng-click="nfe_events(document, $event); setSelectedDocument(document.id)">
Eventos do Documento
</md-button>
</md-menu-item>
</md-menu-content>
</md-menu>
</td>
答案 0 :(得分:1)
您可以对ng-repeats进行的最佳性能改进之一是填充您在块中重复的数组,以便分批呈现表行而不是一次性呈现。这允许浏览器在渲染表时执行其他操作,而不是将所有精力都集中在渲染表上。
在实践中,你可以在你的成功函数中做这样的事情(使用$ q链接promises和Lodash使分块变得更容易)并且当文档被添加到$ scope上的文档数组时它们将被渲染到DOM:
$scope.promise = $http.get("/documents.json",
{ "params": {"company_id": company_id} }
).success(
function(data,status,headers,config) {
let collection = data.data;
// split the collection into smaller chunks; pick the size of each batch here
let chunkedCollection = _.chunk(collection, size);
let nextToRender;
let promise = $q.resolve();
function renderChunk(chunk) {
// returning a $timeout ensures that each chunk is queued to be rendered seperately
Array.prototype.push.apply($scope.documents, chunk);
return $timeout(function(){}, 0);
}
_.forEach(chunkedCollection, function(chunk, index) {
// we need to bind each chunk to the render function because of the $timeout
nextToRender = renderChunk.bind(null, chunk);
// $timeout returns a promise, so it's necessary to chain them like this
promise = promise.then(nextToRender);
});
$scope.totalItems = data.paging;
console.log("HERE");
}).error(
function(data,status,headers,config) {
toastr.error("Error.");
});
答案 1 :(得分:0)
您可以在此处进行常见的性能增强,实际上是将代码移至服务中,然后将您的服务注入md-row
以访问您的数据。这里性能如此之慢的一个重要原因是因为md-row指令中的作用域绑定。所以..
在服务中获取数据,然后将值分配给服务。
创建一个没有范围绑定的md-table-content类型指令,该指令将服务注入其中,然后将服务变量的值分配给范围。
将ng-repeat移动到md-table-content指令的模板中,并在md-table-content上创建$ scope变量或函数,以便更快地评估该巨型ng-class逻辑。或者更好的是尝试将其中一些类折叠成if = document.id - &gt;的简单逻辑。申请活跃,否则申请非活跃或类似的行