角度材料md-select和ng-repeat的性能缓慢

时间:2016-04-21 08:48:41

标签: angularjs angularjs-ng-repeat angular-material

我正在使用角度和角度材料编写企业应用程序,并且对于中等大小(在我看来)形式的性能存在问题。特别是在IE中。

(工作演示,请参阅https://codepen.io/tkarls/pen/vGrqWv。点击卡片标题,然后在打开前暂停一下。特别是使用IE和移动设备。桌面镀铬工作得非常好。)

表格中最严重的违规者似乎是一些md选择,他们使用ng-repeat。

<md-select ng-model="form.subchannelId" ng-disabled="vm.readOnly">
    <md-option ng-repeat="id in subchannelIds" value="{{::id}}">{{::id}}</md-option>
</md-select>
<md-select ng-model="form.serviceReference" ng-disabled="vm.readOnly">
    <md-option ng-repeat="id in serviceReferences" value="{{::id}}">{{::countryId}}{{::id}}</md-option>
</md-select>
<md-select ng-model="form.audioCodec" ng-disabled="vm.readOnly">
    <md-option ng-repeat="audioCodec in audioCodecs | orderBy:'toString()'" value="{{audioCodec}}">{{::systemVariables.encoders.aac[audioCodec].displayName}}</md-option>
</md-select>
<md-select ng-model="form.audioSource" ng-disabled="vm.readOnly">
    <md-option ng-repeat="audioSource in audioSources | orderBy:'toString()'" value="{{audioSource}}">{{audioSource}}</md-option>
</md-select>
<md-select ng-model="form.padSource" ng-disabled="vm.readOnly">
    <md-option ng-repeat="padSource in padSources | orderBy:'toString()'" value="{{::padSource}}">{{::padSource}}</md-option>
</md-select>
<md-select ng-model="form.lang" ng-disabled="!form.generateStaticPty || vm.readOnly">
    <md-option ng-repeat="langKey in langKeys | orderBy:'toString()'" value="{{::langs[langKey]}}">{{::langKey}}</md-option>
</md-select>
<md-select ng-model="form.pty" ng-disabled="!form.generateStaticPty || vm.readOnly">
    <md-option ng-repeat="ptyKey in ptyKeys | orderBy:'toString()'" value="{{::ptys[ptyKey]}}">{{::ptyKey}}</md-option>
</md-select>

数据模型如下:

$scope.subchannelIds = [0, 1, 2]; //up to 63 in real life
$scope.serviceReferences = ["000", "001", "002"]; //up to 999 in real life
$scope.ptys = {
  "No programme type": 0,
  "News": 1,
  "Current Affairs": 2}; //Up to ~30 in real life
$scope.ptyKeys = Object.keys($scope.ptys);
$scope.langs = {
  "Unknown": "00",
  "Albanian": "01",
  "Breton": "02"}; //Up to ~100 in real life
$scope.langKeys = Object.keys($scope.langs);

其他ng-repeats很小,每个3-5项。我认为现代浏览器应该处理这种大小的数据集并快速渲染它。所以我希望我的HTML代码做得非常糟糕。数据是从现实生活中的服务器获取的,但我预先获取它,所以一旦表单准备好显示它已经在$ scope中。

我在使用普通的js循环获取数据后尝试预生成HTML。然后只插入html代码段:              {{:: preGeneratedHtmlHere}}     

但是角度不会把它视为html而是文字......

有关如何优化此功能的任何帮助表示赞赏!

3 个答案:

答案 0 :(得分:8)

角度材料的性能非常差,因为固定在范围内的物体很大,这使得消化周期非常长且不合格。

您应首先使用默认selectng-optionsDOCS HERE)进行尝试。如果这对您更有效,我建议使用纯HTML,然后使用MaterializeCSS来获得Material Design的外观。

答案 1 :(得分:3)

是的,让所有普通的旧HTML都会加快速度,然而你失去了所有的眼睛糖果。要拥有来自这两个领域的优质部分,您可以进行一些基本的优化。

  1. 你真的需要观看收藏 - 是收藏品吗? 要改变,如果是这样,你可以触发摘要吗?就像你做的那样 使用id你也可以单向绑定重复的集合 好。

    ng-repeat="id in ::serviceReferences"

    1. 你真的不需要 所有选项都预装好了吧?因为你正在使用 角度材料,默认下拉将与交换 多个元素,以模拟下拉行为。我做了 删除选项列表,将其替换为实际选中的 元素并仅在控件获得时填充列表 焦点。见documentation
    2. 我仍然认为角质材料的性能很差。它根本不能很好地扩展。 1-2控制工作,但如果你有超过10控制工作,它会开始失败。

      PS:不要煮美味汤!

答案 2 :(得分:2)

ng-repeat中的大量项目会导致一些问题。当角度使用ng-repeat创建嵌套列表时,将为每个项目创建一个观察者。数百名观察者显然会在moible(可能是IE)上放慢性能。我们在ng-repeat时使用了此问题,因此最佳做法是尽可能避免使用ng-repeat,在您确实需要时创建并附加watcher

所以我认为可能的解决方案是,尝试使用普通for循环而不是ng-repeat