我有一个相对较快的SproutCore应用程序,我试图让它快一点。
现在,当用户滚动我的SC.ListView并且他们滚动查看一些尚未从服务器加载的列表项(例如从关系中)时,应用程序会自动调用服务器来加载这些记录。尽管速度很快,但我的列表项仍然是空白的。
我知道我可以让他们说“加载......”或类似的东西(我有),但我想知道:有没有办法预加载我的“屏幕外”记录,以便在用户滚动时,列表项已加载?
我的ListItemViews相当大(按像素),所以即使从AJAX的角度来看,加载双倍的数据也不会成为杀手,如果用户滚动,内容总是被加载会很好(除非他们滚动SUPER-SUPER-fast,在这种情况下我可以看到加载指示器。)
我目前通过将以下内容添加到我的SC.ListView中找到了解决方案,但我注意到移动设备上的一些主要性能问题,它们与进行此更改直接相关,所以我想知道是否有更好的方法。
contentIndexesInRect: function(rect) {
rect.height = rect.height * 2;
return sc_super();
}
答案 0 :(得分:1)
覆盖contentIndexesInRect是我这样做的方式。我会做不到两倍 - 我可能会从sc_super()获得结果,然后在结果索引集中添加一些额外的项。 (我相信它会被冻结,所以你可能需要克隆 - 编辑 - 冻结。)一两个额外的可能会给你足够的喘息空间来加载这些东西,而不会对明显的性能问题做出多少贡献。
我很惊讶它会导致重大的性能问题。听起来像你的列表项目本身可能比它们需要的更重 - 例如,它们可能有许多绑定钩子和解钩。如果这是正在发生的事情,您可以从提高效率中获益更多。
答案 1 :(得分:0)
我认为您可以更好地加载列表实际显示内容的上下文 之外的其他数据。例如,强制要渲染更多列表项以触发其他请求 会导致额外数据可用,但也会向DOM添加几个不必要的元素,这实际上对整体性能有害。事实上,一旦你获得了足够数量的额外内容,这些额外元素很可能是移动设备大幅放缓的原因。
相反,我首先要确保您的列表项视图正确汇集,以便只有可见项正在使用尽可能少的DOM操作更新到位。然后,在请求所需数据后,我会懒得加载其他数据 。根据您的设置,有很多方法可以做到这一点。您可能希望向数据源添加一些逻辑以在每个填充的请求范围上触发其他请求,或者您可能希望执行类似itemViewForContentIndex
中的覆盖SC.CollectionView
作为触发额外数据的点。无论哪种情况,我想它看起来都像这样,
// …
prefetchTriggered: function (lastIndex) {
// A query that will fetch more data (this depends totally on your setup).
var query = SC.Query.remote(MyApp.Record, {
// Parameters to pass to the data source so it knows what to request.
lastIndex: lastIndex
});
// Run the query.
MyApp.store.find(query);
},
// …
正如我在上面的评论中提到的,请求的结构完全取决于您的设置和API,因此您必须对其进行修改以满足您的需求。如果您能够请求合适的项目范围,而不是一次一个,那么它会更好。