AngularJS在显示表格时性能极差:(1.6.5)

时间:2017-12-05 14:50:21

标签: angularjs performance group-by html-table angularjs-ng-repeat

我们正在构建一个应用程序来显示包含时间表数据的表。 在界面上,用户可以设置不同的过滤器。

我可以使用数据网格来加速一切。 我可以使用没有分组的表,并使用某种懒惰的提取,这将加快速度。 但是我们喜欢布局。 结果是手表超过了2000年,我们遇到了瓶颈。这不是我们显示百分之一行。

我们怎样才能使这个性能更高一些。 我试过跟踪,但没有改进。我尝试过bind-once,但那也没有用。 (老实说,我不知道如何使它与键值对象一起工作)。 一个性能技巧可能是更改过滤器,在控制器中移动和链接它们?

正如您所看到的,我们会重复使用相同的过滤器,但这对于分组来说是必要的。

我还没有看到任何适用于这种自定义表/组的懒惰机制。

希望你能帮助我指出正确的方向,因为我真的很喜欢当前的布局。

数据集显示在表格中,并按日期分组。

示例输出:

hrefDateA | hrefDateB | hrefDateC | hrefDateD

DateA

RowA with columns

RowB with columns

RowC with columns

DateB

RowD with columns

RowE with columns

DATEC

RowA with columns

RowB with columns

RowC with columns

...

<div ng-if="includeDesktopTemplate" ng-show="whateverdata.length > 0">
        <div>
            Jump to:
            <a ng-href="#tableheader{{$index}}" ng-repeat="(key, value) in whateverdata | filter:filterA() | filter:filterB() | filter:filterC() | groupBy: 'someproperty'" class="someclass">
                {{key}}
            </a>
        </div>
        <hr />
        <table>
            <thead>
                <tr>
                    <th class="timetablerow">HeaderA</th>
                    <th class="timetablerow">HeaderB</th>
                    <th class="timetablerow">HeaderC</th>
                    <th class="timetablerow">HeaderD</th>
                    <th class="timetablerow">HeaderE</th>
                    <th class="timetablerow">HeaderF</th>
                </tr>
            </thead>
            <tbody ng-repeat="(key, value) in whateverdata | filter:filterA() | filter:filterB() | filter:filterC() | groupBy: 'someproperty'">
                <tr>
                    <td colspan="6" class="desktoptablegroupby" id="tableheader{{$index}}">
                        {{key}}
                    </td>
                </tr>
                <tr>
                    <td colspan="6">
                        <hr class="redbackground" />
                    </td>
                </tr>
                <tr ng-repeat="row in value | filter:filterA() | filter:filterB() | filter:filterC()" ng-class-odd="'odd'" ng-class-even="'even'">
                    <td class="timetablerow">
                        {{row.propertyA}}
                    </td>
                    <td class="timetablerow">
                        {{row.propertyB}}
                    </td>
                    <td class="timetablerow">
                        {{row.propertyC}} - {{row.propertyD}}
                    </td>
                    <td class="timetablerow">
                        {{row.propertyD}}
                    </td>
                    <td class="timetablerow">
                        {{row.propertyE}}
                    </td>
                    <td class="timetablerow">
                        <div ng-show="{{row.propertyF}}">
                                <md-tooltip md-direction="{{tooltip.tipDirection}}">
                                    {{row.propertyF}}
                                </md-tooltip>
                                <md-icon md-svg-src="~/Content/comment.svg">
                                </md-icon>
                        </div>
                    </td>
                </tr>
            </tbody>
        </table>
        <br /><br />
    </div>

如果我包含以下代码,手表可以从3k到6k

<div ng-show="{{row.propertyF}}">
                            <md-tooltip md-direction="{{tooltip.tipDirection}}">
                                {{row.propertyF}}
                            </md-tooltip>
                            <md-icon md-svg-src="~/Content/comment.svg">
                            </md-icon>
                    </div>

关于上面的代码。只有当字段包含数据时,一列才会显示带有工具提示的图标,该工具提示包含数据集的额外字段的值。但是这也会在使用过滤器时产生问题(因此重绘屏幕),因为其他行显示工具提示,即使特定行的字段值不包含值。(DOM / update / filter问题?)

1 个答案:

答案 0 :(得分:0)

这是AngularJS处理变更检测和渲染的方式的限制。真的没有简单的解决方案 - 强调简单。我在几个场合所做的是使用一种经常被称为虚拟滚动/虚拟重复的技术。它基本上做的是它只渲染可以在视口中看到的元素,但是在列表/表的顶部和底部添加偏移量以使滚动条保持恒定大小,而不管实际渲染了多少元素。然后,无论何时滚动,弹出视图的元素在可见之前都会无缝渲染。这给人一种错觉,即它只是一个长列表/表,当它真正只呈现可见的内容时。

有许多库实现了这种技术。我个人有一个名为angular-vs-repeat的经验,但你应该看看一些最适合你用例的评估。我还有一次实现了我自己的虚拟滚动,它确实可行(我在这种情况下的用例是我需要虚拟滚动才能垂直和水平工作)。