如何提高单页面应用程序的性能?

Dav*_*ite 5 performance ruby-on-rails backbone.js ruby-on-rails-3 rabl

简介
我有一个(主要)单页面应用程序,使用BackboneJS和Rails后端构建.

因为大多数交互发生在webapp的一个页面上,所以当用户第一次访问页面时,我基本上必须在一个大的深度连接查询中从数据库中提取大量信息.

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

加载时间

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

快速的methid电话

现在我已经完成了所有我可以做的急切加载(我使用Bullet宝石查看)并且我仍然有问题.

这些方法调用很可能在我的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
Run Code Online (Sandbox Code Playgroud)

所以我似乎需要对此​​做点什么,但我不确定采取什么方法.以下列出了我的潜在想法:

绩效改进的想法

愚蠢的界面
也许我可以想出办法向用户提供不需要实际数据的信息.我不明白为什么我绝对需要这样做,但是其他单页应用程序(如Trello)的界面非常复杂.

概念分页
如果我对概念进行分页,它将减少每次从数据库中提取的数据量.产品会是一个劣质的用户界面.

缓存
目前,刷新页面只会再次从数据库中提取整个搜索.也许我可以缓存部分应用程序以减少数据库命中.这看起来很混乱,因为我正在处理的数据不多是静态的.

多个请求
在没有将JSON嵌入到页面中的情况下服务页面在技术上是不好的,但是如果我加载未填充的页面然后获取数据,用户可能会觉得事情发生得更快.

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

将方法调用移动到DB中
也许我可以将我在视图层中执行的迭代的一些结果缓存到数据库中,然后将它们拉出来而不是计算它们.或者我可以在写入而不是在读取时同步事物.

问题
有没有人对我应该花多少时间有任何建议?

小智 1

如果无法看到实际的用户界面,这是一个很难回答的问题,但我会专注于仅加载显示初始界面所需的数据。例如,如果用户必须深入查看您所呈现的某些数据,那么您可以按需加载该数据,而不是将其作为初始负载的一部分加载。您提到一次搜索可以有多达 100 个“概念”,也许您最初不需要获取所有这些概念?

最重要的是,听起来你的问题并不是真的在客户端——听起来你的服务器端代码正在减慢速度,所以我会探索你可以做些什么来获取更少的数据,或者推迟复杂的查询,直到确实需要它们为止。