2011-10-20 24 views
2

をスピードアップ、私は関連する3つのモデルがあります:セグメントは各GeoPointOnSegmentsとして保存協会と、2 GeoPointsを持っています。サーバー側では、has_many:throughの関係を持つ簡単なRailsコードです。クライアント側では、私が書いたバックボーンコードは以下の通りです。 (注:私はクライアント側でデータを作成してから一括アップロードすることができますが、ローカルIDとサーバーIDの両方を処理するロジックがある理由です)。BACKBONE.JSモデルとの関係:パフォーマンス

このコードは非常に遅いです私は何百ものモデルを持っています。

masterRouter.geo_point_on_segments.select ... 

与えGeoPointに接続されているものを見つけるためにすべての単一のGeoPointOnEntryモデルにフィルタをやっている:具体的には、geo_point.coffeeに次の行です。 (GeoPointに複数のSegmentが接続されていることに注意してください)パフォーマンスを改善する方法の提案はありますか?私が持っていた

アイデア:

  • それはおそらくいくつかの冗長性と、ネストされたJSONを生成し、サーバ側で
  • を提供するために何かを持っていると仮定https://github.com/PaulUithol/Backbone-relationalによって提供される機能をご利用ください。
  • JavaScriptハッシュを使用してソートのクライアント側インデックスを作成します。

他にも優れたアイデアはありますか?

geo_point.coffee

class App.Models.GeoPoint extends Backbone.Model 
    name: 'geo_point' 
    getGeoPointOnSegments: -> 
    masterRouter.geo_point_on_segments.select (gpos) => 
     if @isNew() 
     return gpos.get('geo_point_cid') == @cid 
     else 
     return gpos.get('geo_point_id') == @id 
    , this 
    getSegments: -> 
    _.compact _.map @getGeoPointOnSegments(), (gpos) => 
     gpos.getSegment() unless gpos.get('markedForDelete') 
    getConnectedGeoPoints: -> 
    _.compact _.flatten _.map @getSegments(), (s) => 
     s.getGeoPoints() unless s.get('markedForDelete') 

geo_point_on_segment.coffee

class App.Models.GeoPointOnSegment extends Backbone.Model 
    name: 'geo_point_on_segment' 
    getGeoPoint: -> 
    if local = masterRouter.geo_points.getByCid(@get 'geo_point_cid') 
     return local 
    else if server = masterRouter.geo_points.get(@get 'geo_point_id') 
     return server 
    getSegment: -> 
    if local = masterRouter.segments.getByCid(@get 'segment_cid') 
     return local 
    else if server = masterRouter.segments.get(@get 'segment_id') 
     return server 

segment.coffee

class App.Models.Segment extends Backbone.Model 
    name: 'segment' 
    getGeoPointOnSegments: -> 
    _.compact masterRouter.geo_point_on_segments.select (gpos) => 
     if gpos.isNew() 
     return gpos.get('segment_cid') == @cid 
     else if gpos.get('markedForDelete') 
     return null 
     else 
     return gpos.get('segment_id') == @id 
    , this 
    getGeoPoints: -> 
    _.map @getGeoPointOnSegments(), (gpos) => 
     gpos.getGeoPoint() unless gpos.get('markedForDelete') 

答えて

0

Iトン関係モデル、GeoPointOnSegmentをバックボーンに持たない方がいいでしょう。

Iが動作したい構造は以下の通りである:

  • 各点は、それが
  • に属するセグメントのコレクションを有し、各セグメント有するポイントで収集/アレイ

このJSONからデータをインスタンス化するときに、次のような操作を行うと簡単に実行できます。

  • initialすべての点をizeする
  • 各GeoPointOnSegmentに対してすべてのセグメント
  • を初期化し、そのポイントをセグメントのコレクションに追加し、セグメントをポイントのコレクションに追加します。ポイントとセグメントのコレクションを取得するのは、ID(およびバックボーンによってインデックス付けされている)のように高速です。

また、新しいセグメントを作成する場合は、これらの関連付けを維持する必要があります。

これはクライアント側のインデックスですが、モデルに統合されています。