美文网首页
IM性能优化

IM性能优化

作者: tangyefei | 来源:发表于2018-08-16 13:28 被阅读60次

优化之前的性能表现

短时间内收到消息数过多比如1秒钟20条消息,网页卡顿/浏览器Crash掉,Chrome 的CPU使用率飙到100%以上。

消息接收的处理过程

  • 通过更新IM.vue中的ims来渲染消息内容
  • 通过更新Vuex中的IMList来刷新会话列表
    • 查询IMList,找到当前消息所属会话
    • 如果,当前消息不在会话中,重新拉取会话
    • 如果,当前消息在会话中,更新会话信息,更新未读消息总数,并根据更新时间进行排序
      • 会话信息包含:未读数、最近一条消息内容、最新的更新时间

最终排查的问题

最初的设想,每秒钟n条消息,上述的处理过程需要走n遍,因此计划通过setInterval来进行批次处理,比如200毫秒处理一次。实现后,问题变成浏览器Crash,到当前网页的Crash,Chrome CPU的使用率仍旧非常高。最终排查得到的性能问题在于结论是

  • 频繁更新IMList非常耗费性能,包括修改数值、插入会话、排序
  • 不必要的接口调用,比如重新调用会话列表,将所有会话涉及的账号数据一次请求回来

优化策略为

  • 替换直接查询会话为更新会话(增、删、更新)
  • 会话中涉及的动态消息,即IMList中每个会话的updatedAt、count、msgBody转移到Vuex外面
  • 重写整套排序逻辑,即根据实际的业务场景来决定如何调整排序,例如,新会话进来直接插入到会话的顶部
  • 后台接口调用延后,单聊群聊中涉及的账号信息,改为全部请求为只请求单聊中涉及的信息,群聊中改为选中群聊再请求

转移后台的计算策略到前台

最初的逻辑是:

  • 每一条消息有一个唯一的requetId标识,前台负责告诉服务器,自己是否读了这条消息
    • 在会话中,来一条消息,直接告诉服务端,已经读过这条消息了
    • 在新进入的会话中,在调用消息列表的接口中,服务器将所有消息都设置为,该用户已读
  • 服务器端,收到拉取会话的请求时
    • 获取到会话消息并且标记该用户对单条消息的已读未读
    • 统计群聊内所有用户对消息的已读未读,并推送给前端

优化后的逻辑是:

后台只返还每个群聊成员,阅读到的消息的seqNo,seqNo是根据消息前后顺序,数值逐渐递增的,前台根据返回数据对每一条未读消息进行计算,举例如下

群聊中有 A B C D三人,A 发送了4条消息,分别为 a1 a2 a3 a4

其中B读到了a2,C读到了a3,D读到了a4,那么计算逻辑为

a1=0 0人读到的最远位置
a2=1 1人读到的最远位置
a3=1 1人读到的最远位置
a4 =1 1人读到的最远位置

sa4 = a4 = 0
sa3 = a3 + sa4 = 1 + 0 = 1
sa2 = a2 + sa3 = 1 + 1 = 2
sa1 = a1 + sa2 = 1 + 2 = 3

其他待优化的点

  • 会话消息数量过多时如何展示?动态渲染(Recycle List)。

相关文章

网友评论

      本文标题:IM性能优化

      本文链接:https://www.haomeiwen.com/subject/veugpftx.html