繁体   English   中英

加载一长串Facebook好友的表现

[英]Improving performance on loading a long list of facebook friends

在此输入图像描述

作为我的rails项目的一部分,我有一个功能,允许用户向他们的FB朋友发出邀请。 我正在使用fb_graph进行API调用,下面是用户点击邀请页面时控制器代码的示例。

这个操作非常昂贵。 我发现拥有超过1000个朋友的用户需要超过30秒的时间。 此外,每次用户点击邀请页面时,此代码都会重新执行。 虽然用户的FB好友列表并不完全是静态的,但是在每次请求时都不应该重新计算。

所以我想要做的就是改进这个代码并使其更有效率。 我可以想到几种不同的潜在方法可以做到这一点,但在这种情况下最有意义的是什么? 这比我通常想要的那样开放得多,但是由于我还是比较新的编程,我很好奇你会做什么/不做什么和怎么做它。

以下是我可以进行优化的一些想法:

1)仅在会话中进行优化。 代码在第一次命中页面时执行,并将在会话的其余部分持续存在。 我其实不知道怎么做。

2)坚持到数据库。 将列添加到将保存朋友哈希的用户表。 我可以使用后台工作定期刷新这些数据(也许每周一次?)

3)坚持缓存。 我甚至不确定这涉及到什么,或者这是否是一个合适的用例。 我的感觉是选项2需要大量的手动维护,并且可能有一个很好的缓存解决方案来处理到期等,但不确定

其他想法? 感谢您对选项的看法。

  # fetch full array of facebook friends
  @fb_friends = current_user.facebook.fetch.friends

  # strip out only id, name, and photo for each friend
  @fb_friends.map! { |f| { identifier: f.identifier, name: f.name, picture: f.picture }}

  # sort alphabetically by first name
  @fb_friends.sort! { |a,b| a[:name].downcase <=> b[:name].downcase }

  # split into two lists. those already on vs not on network
  @fb_friends_on_network =  Array.new

  @fb_friends.each do |friend|
    friend_find = Authorization.find_by_uid_and_provider(friend[:identifier], 'facebook')
    if friend_find
      @fb_friends_on_network << friend_find.user_id
      @fb_friends.delete(friend)
    end 
  end

更新#1

在我进行的初步实验中添加了更多。 我在我的用户表中添加了一个包含@fb_friends数组的列(对上面显示的转换进行后处理)。 基本上上面的控制器代码只用@fb_friends = current_user.fbfriends替换。 我认为这会显着减少负载,因为没有更多的Facebook呼叫,更不用说上面所做的所有处理。 这确实节省了一些时间,但没有预期的那么多。 我自己的朋友列表需要大约6秒才能加载到我的本地计算机上,之后将其更改为4秒。 我必须在负载问题上遗漏更大的东西。

更新#2

经过进一步调查,我了解到几乎一半的数据传输都归因于我用于“邀请”按钮的表单。 表单会为每个朋友加载一次,看起来像这样:

<%= form_for([@group, @invitation], :remote => true, :html => { :'data-type' => 'html', :class => 'fbinvite_form', :id => friend[:identifier]}) do |f| %>
    <%= f.hidden_field :recipient_email, :value => "facebook@meetcody.com" %>

    <div class = "fbinvite btn_list_right" id = "<%= friend[:identifier] %>">
    <%= f.submit "Invite", :class => "btn btn-medium btn-primary", :name => "fb" %>
    </div>
<% end %>

我决定删除表单并在里面放一个简单的按钮:

<div class = "fbinvite_form" id = "<%= friend[:identifier] %>" name = "fb">
    <div class = "btn btn-small">
        Invite
    </div>
</div>

然后我使用ajax来检测点击并采取适当的措施。 这一变化从字面上将数据传输减少了一半。 在装载约500名朋友之前需要〜650kb,现在它下降到~330kb。

我想我会回去试试我在Update#1中尝试过的,进行预处理。 结合我希望我可以把它降低到约2秒的操作。

更新#3

我最后安装Miniprofiler以了解更多可能会减慢此操作的速度,并了解到我的for循环是非常低效的,因为它会让每个朋友都去DB。 我发布了一个单独的问题,并帮助将旅行减少到一个。 然后我继续执行我在Update#1中提到的预处理。 有了所有这些变化,我把它降到了约700毫秒,这是非常值得注意的,因为它在走这条道路之前需要+20秒加上!

如果你可以并行运行一些查询,我建议你去看看: futoroscope gem 正如您在宣布的博客文章中所看到的,它试图解决同时进行API查询的同样问题。 它似乎有很好的支持和良好的测试覆盖率。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM