2012-05-05 192 views
5

介绍
我有一个(主要)单页application与BackboneJS和Rails后端构建。因为大多数交互发生在webapp的一个页面上,所以当用户第一次访问页面时,我基本上必须从一个大的深度连接查询中将大量信息从数据库中提取出来。如何提高单页面应用程序的性能?

这导致我在这一页上有一些相当极端的加载时间。

load times

NewRelic的似乎是告诉我,我的大部分问题都是因为个人457所快速方法调用。

fast methid calls

现在我已经做了所有的预先加载,我可以做(我与Bullet gem选中),我仍然有一个问题。

这些方法调用很可能发生在我的Rabl序列化程序中,我使用它来序列化一堆JSON以嵌入到初始化Backbone的页面中。你不需要了解所有这些,但足以说它可以加起来457个方法调用。

object @search 
attributes :id, :name, :subscription_limit 

# NOTE: Include a list of the members of this search. 
child :searchers => :searchers do 
    attributes :id, :name, :gravatar_icon 
end 

# Each search has many concepts (there could be over 100 of them). 
child :concepts do |search| 
    attributes :id, :title, :search_id, :created_at 

    # The person who suggested each concept. 
    child :suggester => :suggester do 
    attributes :id, :name, :gravatar_icon 
    end 

    # Each concept has many suggestions (approx. 4 each). 
    node :suggestions do |concept| 
    # Here I'm scoping suggestions to only ones which meet certain conditions. 
    partial "suggestions/show", object: concept.active_suggestions 
    end 

    # Add a boolean flag to tell if the concept is a favourite or not. 
    node :favourite_id do |concept| 
    # Another method call which occurs for each concept. 
    concept.favourite_id_for(current_user) 
    end 
end 

# Each search has subscriptions to certain services (approx. 4). 
child :service_subscriptions do 
    # This contains a few attributes and 2 fairly innocuous method calls. 
    extends "service_subscriptions/show" 
end 

因此,我似乎需要做些什么,但我不知道采取什么方法。下面是我有潜在的一系列意见:

性能改进意见

向上兼容的接口
也许我能想出的办法将信息呈现给不需要实际的用户数据存在。我不明白为什么我绝对需要这样做,但其他单页应用程序(如Trello)具有令人难以置信的复杂界面。

概念分页
如果我概念分页,它会减少每次从数据库中提取的数据量。尽管如此,产品将会劣质用户界面。

缓存
目前,刷新页面只是将整个搜索从数据库中提取出来。也许我可以缓存部分应用程序以减少数据库访问次数。这似乎很混乱,虽然因为我处理的数据并不多。

多请求
这在技术上是坏的服务页面而不嵌入JSON到页面,但也许用户会感觉事情正在发生更快,如果我加载页面无人居住,然后获取数据。

索引
我应该确保我所有的外键都有索引。我还应该尝试考虑有助于建立索引的地方(如收藏夹?)并添加它们。

将方法调用到数据库
也许我可以将我在视图层中进行的迭代的一些结果缓存到数据库中,然后将它们拉出而不是计算它们。或者我可以在写作而不是在阅读上同步。

问题
有没有人有什么建议,我应该花什么时间?

回答

1

这是一个很难回答的问题,却无法看到实际的用户界面,但我只会专注于只加载显示初始界面所需的数据。例如,如果用户不得不向下钻取以查看您正在呈现的一些数据,则可以按需加载该数据,而不是将其作为初始有效载荷的一部分加载。你提到搜索可能有多达100个“概念”,也许你不需要最初获取所有这些概念?

底线,它听起来不像你的问题真的在客户端 - 听起来你的服务器端代码正在放慢速度,所以我会探索你可以做些什么来获取更少的数据,或推迟复杂的查询,直到他们肯定需要。

1

我建议将你的JS代码库分离成使用像RequireJS这样的资产加载器动态加载的模块。这样你就不会有太多的XHR在加载时触发。

当需要特定的模块时,它可以在适当的时间加载和初始化,而不是每次加载页面。

如果您稍微复杂一点,每个模块都应该能够启动和停止。因此,如果您有任何polling发生或复杂的代码执行,您可以停止模块以提高性能并减少网络负载。

+0

虽然我同意优化资产交付是提高绩效的重要一步,但我不认为这是我在这里遇到的主要问题。虽然应用程序中有一串JS,但它被压缩,缩小并以大约100kb的速度到达。它也应该被缓存在客户端,这样重复访问者的加载成本就会降到最低。 –