web-dev-qa-db-ja.com

IE11はAngularJSのng-repeatレンダリングで遅く/フリーズします

現在、IE11とAngularJSで解決すべき非常に微妙な問題があります。

私のページは、任意のタブ内にテーブルを持つタブセットを作成するための2つのネストされたng-repeatで構成されています。

ここにコードがあります: http://Pastebin.com/0fffPz5Z

コードでは、各アプリケーションのオブジェクトには、約1.000個のアイテムの関連オブジェクトがあります。 Chrome、Safari、Mozillaを使えば問題ありません、すべてが超高速です! IE11を使用すると、ページが遅くなり、IE11はページのスクリプトが遅すぎるというメッセージを表示します。

この結果でIE11インターフェイスのプロファイリングを作成しました: https://www.dropbox.com/s/y5xuystxht6gjkr/IE11-interface-profiling.png?dl=

これは別のIE11のバグですか?私の英語で申し訳ありません、そしてどんな提案にも前もって感謝します。

編集:現在(「デバッグ」の目的で)すべてのtdのコンテンツを削除しました... IE11はまだ遅すぎます。 :(

                <tabset ng-show="!applicationsLoading">
                <tab ng-repeat="application in applications track by application.name">
                    <tab-heading>
                        <em class="fa fa-clock-o fa-fw"></em> {{ application.name }}
                    </tab-heading>
                    <div>
                        <!-- START table responsive-->
                        <div class="table-responsive">
                            <table class="table table-bordered table-hover table-striped">
                                <thead>
                                <tr>
                                    <th></th>
                                    <th></th>
                                    <th></th>
                                    <th></th>
                                    <th></th>
                                    <th></th>
                                    <th></th>
                                </tr>
                                </thead>
                                <tbody>
                                <tr ng-repeat="item in application.items track by item.itemid">
                                    <td></td>
                                    <td></td>
                                    <td>
                                    </td>
                                    <td></td>
                                    <td></td>
                                    <td>
                                    </td>
                                    <!-- Graph or History column -->
                                    <td>
                                    </td>
                                </tr>
                                </tbody>
                            </table>
                        </div>
                        <!-- END table responsive-->
                    </div>
                </tab>
            </tabset>
11
Fabrizio A

AngularJsには、ページごとのバインディングのレンダリングに制限があります(一部の記事では、約2000のバインディングであることがわかります)。現在、あなたはこの状況に直面しています。 chromeとMozillaがスムーズに機能する理由は、それらのDOM操作がより適切に最適化されているためです。パフォーマンスを向上させるには、次のことを試してください。

  • ng-repeatでの並べ替えの使用は避けてください(挿入前に並べ替えます)
  • ワンタイムバインディングを使用する(::構文)
  • 不要な時計を外す
  • ダイジェストサイクルを最適化する
  • ページネーションを使用する
  • Anglejs ng-repeatをReactJsコンポーネントに置き換えます(データ量が非常に多い場合)
19
nesteant

これと同じ問題が発生しました。 Chromeですべてが完全に機能し、IEでテストしたところ、1000レコードを超えるとクラッシュし続けました。

このリンク をたどって、テーブルに「遅延読み込み」または「無限スクロール」を追加することになりました。したがって、テーブルのロード時に、1000以上のレコードすべてがプルされますが、このデータをテーブルに直接ロードする代わりに、大きな配列にロードしてから、たとえば50レコードのテーブルをサブセット化します。次に、テーブルのスクロールをリッスンするディレクティブを作成し、それが下部に近づいたら、大きな配列から次の50レコードをテーブル配列に追加する関数を起動します。これが直接 フィドルへのリンク 上記のリンクからです。

[〜#〜] html [〜#〜]

<tbody when-scroll-ends="loadMoreRecords()">
    <tr ng-repeat="row in tableData">
        <td>{{row.attribute}}</td>
    </tr>
</tbody>

モジュール

angular.module(myApp, []).directive('whenScrollEnds', function () {
    return {
        restrict: "A",
        link: function (scope, element, attrs) {
            var processingScroll = false;

            var visibleHeight = element.height();
            var threshold = 200;

            element.scroll(function () {
                var scrollableHeight = element.prop('scrollHeight');
                var hiddenContentHeight = scrollableHeight - visibleHeight;

                if (hiddenContentHeight - element.scrollTop() <= threshold) {
                    // Scroll is almost at the bottom. Loading more rows
                    scope.$apply(attrs.whenScrollEnds);
                }
            });
        }
    };
});

コントローラー

function loadTableData() {
    LoadDataService().getData().then(function(response) {
        fullTableList = response.data;
        $scope.tableData = fullTableList.slice(0,50);
    });
}

function loadMoreRecords() {
    // if there's still more than 20 records left, add the next chunk of 20
    if (fullTableList.length - $scope.tableData.length > 20) {
        $scope.tableData = $scope.tableData.concat(fullTableList.slice($scope.tableData.length,$scope.tableData.length + 20));
    } else {
        while ($scope.tableData.length < fullTableList.length) {
            $scope.tableData.Push(fullTableList[$scope.tableData.length]);
        }
    }
}
3
amallard