6

我正在使用 AngularJS 1.0.8。

问题:我有一个动态网站,它可以由各种组件或小部件构建:段落、文本块、图像、超链接和表格,就此而言。段落是更多组件的容器。表也​​是一种容器——它可以容纳其他组件,并将它们排列为数据网格。

该网站不是静态的,即我没有这些组件的预定义布局。相反,我在启动时得到了一个 JSON,它指定了组件的布局。

最初,我对每个此类组件都有一个指令,使用该指令的模板,偶尔使用 $compile 为更复杂的组件更改 DOM。对于“容器”组件——段落和表格——我使用 ngRepeat 来呈现包含在该容器组件中的所有组件。

这在性能方面是有问题的。在 Chrome/Firefox 上加载网站需要几秒钟,时间主要花在 AngularJS 渲染机制上(不是在 IO 中,我想)。

所以我决定改变这些组件的指令。而不是使用 ngRepeat,因为我不需要双向绑定(网站中的内容不是交互式的,无法更改,所以实际上我只需要渲染一次,非常像 servlet ) - 我自己在指令中构建了 HTML 字符串,使用纯 JS,迭代模型中存在的所有包含的组件,最后我编译并链接它。

结果又不够好。对于一个包含数百个单元格的表格,在现代 Chrome/Firefox 中链接需要大约 500 英里,在 IE9 中需要大约 4000 英里,在 IE8 中需要大约 15000 英里,而且 IE7 仍在渲染,所以我不能给你时间:)

我认为问题可能与指令的广泛使用有关。
一个简单的:

<div my-table-component data="data"></div>

在链接之后,元素会产生一个<table>带有 30-40 个标签的<tr>标签,每个标签有 10 个<td>标签,并且每个标签中都会有一个额外的<div my-text-component><div my-image-component>必须自行编译和链接的标签(因为它有一个指令)。

我虽然因为我的网站一开始就不是交互式的,所以我真的不需要这个。也许我可以避免为每个组件使用指令,而只为容器组件留下一个指令。在这些指令中,我将创建每个可能的其他组件的实际 HTML 模板,而不是使用会执行此操作的指令。

这让我从 AngularJS 的想法向 servlet 的想法又迈进了一步。这有点糟糕。所以也许你们中的一个人可以为我提供更好的方法......也许性能问题甚至不存在?即使有这么多的项目,也许使用指令(希望是 ngRepeat)在性能方面也可以很好?除了使用 Chrome 的开发者工具、Firebug 和 Chrome 的 Batarang AngularJS 扩展(它们都没有真正以有效的方式指导我)之外,也许还有更好的方法来进行有洞察力的性能基准测试。

4

1 回答 1

2

使用大量嵌套指令本身不是问题,但任何广泛的绑定都可能产生巨大的影响。

如果有人仍在寻找答案,使用 Angular 1.3+,OP 可以通过首先对他说“不需要双向绑定”的所有元素使用一次性绑定来解决他的问题,使用::binding句法。

此外,我建议尝试使用以下网站中令人惊叹的分析片段来确定哪些绑定特别慢:http: //bahmutov.calepin.co/improving-angular-web-app-performance-example.html

最后,在 Angular 中,尤其是在构建大型 ng 重复表时,通常花费最多时间的是编译阶段。因此,如果可能,请尝试仅构建有限数量的元素(使用limitTo),然后在用户滚动时加载更多元素。许多指令解决了这个问题(寻找“无限滚动”)

总而言之,我认为尝试优化 Angular 应用程序而不是切换到原生 JS 仍然值得,大多数情况下延迟来自开发人员的错误:一些应用程序有数千个观察者并且运行得非常顺利(*咳嗽*喜欢我的*咳嗽*)。

于 2015-03-17T02:05:32.183 回答