2016-10-13 63 views
5

私の現在のアプリケーションでは、かなり長いテーブルを生成してユーザーに表示しています。私は、@ Html.DisplayForの使い方まで追跡した重大なパフォーマンス上の問題を見てきましたが、なぜそれほど確かではありません。ASP.NETでパフォーマンスが遅いDisplayFor ASP.NET MVC

編集:コードサンプルをより簡潔で再現性のある設定に置き換えました。

問題を特定するために、私はVisual Studioのすべてのデフォルト設定を使用して、認証なしで新しいasp.netコアMVCプロジェクトを作成しました。私は、次のようなビューモデルを作成した:ビューは、データを表示することができる最低限である

public IActionResult TestThings() 
    { 
     var list = new List<TestingViewModel>(); 
     for(var i = 0; i < 1000; i++) 
      list.Add(new TestingViewModel {Id = i, TextValue1 = "Test", TextValue2 = "Test2"}); 

     return View(list); 
    } 

:そして

public class TestingViewModel 
{ 
    public int Id { get; set; } 
    public string TextValue1 { get; set; } 
    public string TextValue2 { get; set; } 
} 

ビューに渡すデータとビューモデルを満たすコントローラを追加しました:

@model List<DisplayForTest.ViewModels.TestingViewModel> 

@foreach (var item in Model) 
{ 
    @Html.DisplayFor(m => item.Id) 
    @Html.DisplayFor(m => item.TextValue1) 
    @Html.DisplayFor(m => item.TextValue2) 
} 

このコードを実行すると、実行に1秒以上かかる!原因はDisplayForです。

@model List<DisplayForTest.ViewModels.TestingViewModel> 

@foreach (var item in Model) 
{ 
    @item.Id 
    @item.TextValue1 
    @item.TextValue2 
} 

これは13msでレンダリングされます。 DisplayForがレンダリングに膨大な時間を追加していることは間違いありません。私のPC上では1コールあたり0.4ms近くあります。それは孤立しているわけではありませんが、リストやその他のものにとっては非常に悪い選択です。

DisplayForは本当に遅いですか?または私はそれを間違って使用していますか?

+2

'DisplayFor'は、オブジェクトのすべてのプロパティにアクセスするためにリフレクションを使用します。これは、ナビゲーションプロパティの場合、EF遅延ロードを引き起こす可能性があります。これは起こっている可能性があります。 – Dai

+0

ビューでパーシスタンス・モデルを使用しない理由は、ビュー・モデルを代わりに使用する理由です。 OPが何を使用しているのか分かりませんが、EFCoreには遅延ロードが実装されていません。EF6のみ – Tseng

+0

私はこれにEFCoreを使用しています。私はすばやくビューモデルに変換し、 'Members.Select(s => new MembersListViewModel {Id = s.Id}).ToList();'でデータを選択しましたが、パフォーマンス上の問題は同じようです。 – Doddler

答えて

2

DisplayForは本当に遅いですか?または私はそれを間違って使用していますか?

ラムダ式の評価と実行には少しオーバーヘッドがかかります。最初にフレームワークはvalidate it、次にevaluate itです。 私はここでビットを推測していますが、これはパフォーマンス上の懸念がどこから来ているかのようです。これらの方法の両方は反射を必要とする。

他のすべての表示方法(ValueForDisplayTextForなど)は、あなたの例で同じパフォーマンス効果があります。

なぜ私はMVCチームがデフォルトの足場に使われているか話すことはできませんが、それは私には合っています。 DisplayForは、最も一般的なユースケース(プロパティの値を表示し、カスタムテンプレートを使用してプロパティの値を表示する)と、ほとんどの場合うまくうまく実行することができます。

この場合、生の値(基本的には.ToString)を使用するか、探しているものによってはHtml.Encode/Html.Rawメソッド内で使用することに問題はありません。

+0

このようなカスタム表示テンプレートを必要としないタイプの場合、 'DisplayFor'は過剰ですか?私がこのページにこの数多くのレコードを見せたいと思えば、私はそれに頼ることができないことは明らかです。 10列では、私がレンダリングする各行は、DisplayForを使用してサーバーを4〜5ms使用しますが、これは実際には受け入れられません。私は 'ValueFor'を試してみました。少し速かったのですが、それはまだとても遅かったです。私がそれを使用している主な理由は、足場があなたにそれを自動的に設定するからです。しかし、これが予想される動作であれば、私はそれを答えとして受け入れることができます。 – Doddler

+0

@Doddlerあなたは 'ValueFor'のパフォーマンスについて正しいです - 私の答えは少し外れていました。私は質問によく対処するために私の答えを更新しました。 –

+2

助けてくれてありがとう!ちょっとびっくりした後、通常の型をそのまま出力し、より複雑な型を表示するためにTagHelpersまたはHtmlHelpersを使用しています。私はタグヘルパーのためのいくつかの費用がかかると予想したが、彼らは本当に効率的だね。 – Doddler

関連する問題