简介我有一个(大部分)用 BackboneJS 和 Rails 后端构建的
单页应用程序。
因为大部分交互发生在 webapp 的一个页面上,当用户第一次访问该页面时,我基本上必须在一个大型深度连接查询中从数据库中提取大量信息。
这导致我在这一页上的加载时间相当长。
NewRelic 似乎在告诉我,我的大部分问题是由于 457 个单独的快速方法调用造成的。
现在我已经完成了我能做的所有急切加载(我检查了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 嵌入页面的情况下提供页面在技术上是不好的,但如果我加载未填充的页面然后获取数据,用户可能会觉得事情发生得更快。
索引
我应该确保我的所有外键都有索引。我还应该尝试考虑在哪些地方有索引(例如收藏夹?)并添加它们会有所帮助。
将方法调用移动到数据库
中 也许我可以将我在视图层中所做的一些迭代结果缓存到数据库中,然后将它们拉出来而不是计算它们。或者我可以在写入而不是读取时同步内容。
问题
有人对我应该把时间花在什么方面有任何建议吗?