Javascript Backbone.js模型关系:提高性能
我有三个关联模型:每个线段有两个地质点,关联存储为地质点线段。在服务器端,这是一个简单的Rails代码,具有has_many:through关系。在客户端,以下是我编写的主干代码。(注意:我允许客户端创建数据,然后批量上传;这就是为什么有一些逻辑来处理本地和服务器ID。) 我发现的问题是,当我有数百个模型时,这段代码非常慢。特别是geo_point.coffee中的以下行:Javascript Backbone.js模型关系:提高性能,javascript,performance,backbone.js,coffeescript,Javascript,Performance,Backbone.js,Coffeescript,我有三个关联模型:每个线段有两个地质点,关联存储为地质点线段。在服务器端,这是一个简单的Rails代码,具有has_many:through关系。在客户端,以下是我编写的主干代码。(注意:我允许客户端创建数据,然后批量上传;这就是为什么有一些逻辑来处理本地和服务器ID。) 我发现的问题是,当我有数百个模型时,这段代码非常慢。特别是geo_point.coffee中的以下行: masterRouter.geo_point_on_segments.select ... 这就是对每个单一的地质点尝试
masterRouter.geo_point_on_segments.select ...
这就是对每个单一的地质点尝试模型进行过滤,以找出哪些模型连接到给定的地质点。(请注意,可以有多个线段连接到一个地质点。)关于如何提高性能有何建议
我的想法是:
- 利用通过假设有东西可以提供而提供的功能
- 在服务器端,生成嵌套的JSON,可能有一些冗余
- 使用JavaScript哈希创建排序的客户端索引
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')
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
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')
geo\u point\u on\u细分市场。咖啡
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')
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
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')
细分市场。咖啡
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')
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
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')
我认为最好不要在主干中使用关系模型,
GeoPointOnSegment
我想工作的结构是:
- 每个点都有一个集合及其所属的线段
- 每个段都有一个带点的集合/数组
- 初始化所有点
- 初始化所有段
- 对于每个地质点段,将点添加到段的集合中,并将段添加到点的集合中。检索点和段的集合很快,因为它是按id(并按主干索引)进行的
它是一个客户端索引,但集成在模型中。我认为最好不要在主干中使用关系模型
GeoPointOnSegment
我想工作的结构是:
- 每个点都有一个集合及其所属的线段
- 每个段都有一个带点的集合/数组
- 初始化所有点
- 初始化所有段
- 对于每个地质点段,将点添加到段的集合中,并将段添加到点的集合中。检索点和段的集合很快,因为它是按id(并按主干索引)进行的