gpt4 book ai didi

javascript - Angular 性能 : critical rendering path?

转载 作者:可可西里 更新时间:2023-11-01 13:05:23 26 4
gpt4 key购买 nike

我试图在呈现多行(列最少 25 倍)的表格时优化页面加载速度。

我没有在 Angular 应用程序上调试/改进性能的经验,所以我完全不知道这种速度不足可能涉及什么。

这是 5 行查询的 Chrome 时间线报告:

enter image description here

这是 100 行查询的 Chrome 时间线报告:

enter image description here

XHR 负载(api/list/json/Chemical...)随着在表上呈现更多行而增加。

带有数据的服务器响应快速返回(不是瓶颈):

这是表格的模板:

            <tbody ng-if="compressed">
<tr ng-if="dbos && (rows.length == 0)">
<td class="tableColumnsDocs"><div class="tableButtons">&nbsp;</div></td>
<td class="tableColumnsDocs"><div>No results</div></td>
<td class="tableColumnsDocs" ng-repeat="attobj in columns track by $index" ng-if="$index > 0">
<p>&nbsp;</p>
</td>
</tr>
<tr class="tableRowsDocs" ng-repeat="dbo in rows track by $index">
<td class="tableColumnsDocs"><div ng-include="'link_as_eye_template'"></div></td>
<td class="tableColumnsDocs" ng-repeat="attobj in columns track by $index">
<div ng-init="values = dbo.get4(attobj.key); key = attobj.key; template = attobj.template || getAttributeTemplate(dbo.clazz + attobj.key);">

<div class="content" ng-include="template"></div>
<div class="contentFiller" ng-include="template"></div>
</div>
</td>
</tr>
</tbody>

这里是表格将调用的模板:

<script type="text/ng-template" id="plain_values_template">
<p ng-repeat="v in values track by $index">{{ v }}</p>
</script>

<script type="text/ng-template" id="links_as_dns_template">
<div ng-repeat="dbo in values track by $index" ng-include="'link_as_dn_template'"></div>
</script>

<script type="text/ng-template" id="json_doc_template">
<textarea class="form-control" rows="{{values.length + 2}}" ng-trim="false" ng-readonly="true">{{ values | json }}</textarea>
</script>

<script type="text/ng-template" id="link_as_dn_template">
<a href="#/view/{{ dbo.cid }}"><p>{{ dbo.displayName() }}</p></a>

相关 Controller 部分:

      $scope.getAttributeTemplate = function(str) {
//console.log("getAttributeTemplate"); console.log(str);
if ($templateCache.get(str + ".template")) {
return str + ".template";
}
var a = str.split(/(>|<)/);
//console.log(a);
if ((a.length - 1) % 4 == 0) {
return "links_as_dns_template";
}
var clsname = a[a.length - 3];
if (clsname == "*") {
return "plain_values_template";
}
var attname = a[a.length - 1];
var cls = datamodel.classes[clsname];
var att = cls.attribute[attname];
if (!att) {
return "plain_values_template";
}
if (att.type == "ref") {
return "links_as_dns_template";
}
return "plain_values_template";
};

enter image description here

我不熟悉 Angular 和性能选项。因此,任何有关如何改进的提示或突出显示的不良做法都会非常有帮助!

最佳答案

长表是 Angular 最大的弊端,因为 ng-repeat 等极慢的基本指令

一些简单明了的东西:

我在行/单元格模板中看到很多没有一次性绑定(bind)的绑定(bind) (::)。我认为您的行数据没有发生变化。切换到一次性绑定(bind)将减少观察者数量 -> 性能。

一些更难的东西:

快速回答:

不要让 Angular 处理性能瓶颈

长答案:

ng-repeat 应该编译它的嵌入内容一次。但是使用 ng-include 会扼杀这种效果,导致每一行都对其 ng-include 内容调用编译。在大表中获得良好性能的关键是能够生成(是的,手动,$compile,$interpolate 和东西)一个独特的编译行链接​​函数,尽可能少的 Angular Directive(指令) - 理想情况下只有一次性表达式绑定(bind),并手动处理行成瘾/删除(没有 ng-repeat,你自己的指令,你自己的逻辑)

您至少应该找到一种方法来避免在'ng-repeat="attobj in columns track by $index"' 上出现第二次嵌套的 ng-repeat。这是对每一行的双重重复,杀死编译和链接(渲染性能)和观察者计数(生命周期性能)

编辑:正如所要求的,一个“天真的”例子说明了如何尽可能手动(和快速)地处理表格渲染。请注意,该示例不处理表头的生成,但这通常不是最难的事情。

function myCustomRowCompiler(columns) {

var getCellTemplate = function(attribute) {
// this is tricky as i dont know what your "getAttributeTemplate" method does, but it should be able to return
// the cell template AS HTML -> you maybe would need to load them before, as getting them from your server is async.

// but for example, the naive example to display given attribute would be
return $('<span>').text("{{::model."+ attribute +"}}"); // this is NOT interpolated yet
};


var myRowTemplate = $('<tr class="tableRowsDocs">');

// we construct, column per column, the cells of the template row
_.each(columns, function(colAttribute, cellIdx) {
var cell = $("<td>");
cell.html(getCellTemplate());
cell.appendTo(myRowTemplate);
})

return $compile(myRowTemplate); // this returns the linking function
}

和天真的用法:

function renderTableRows(dbos, columns) {

var $scope; // this would be the scope of your TABLE directive
var tableElement = $el; // this would be your table CONTENT

var rowLinker = myCustomRowCompiler(columns); // note : in real life, you would compile this ONCE, but every time you add rows.


for(var i=0; i<dbos; i++) {
var rowScope = $scope.$new(); // creating a scope for each row
rowScope.model = dbos[0]; // injecting the data model to the row scope
rowLinker(rowScope, function(rowClone) { // note : you HAVE to use the linking function second parameter, else it will not clone the element and always use the template
rowClone.appendTo(tableElement);
});
}

};

这是我在我自己的元素的表格框架中使用的方法(好吧,更高级,但这确实是全局性的想法),允许使用 Angular 功率来渲染单元格内容('getCellTemplate' 实现可以返回html with directive, which will be compiled), using filter even including directives in the cell, but keeping the table rendering logic to myself, to avoid useless ng-repeat watch, 并将编译过热降至最低。

关于javascript - Angular 性能 : critical rendering path?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33825762/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com