当浏览器选项卡没有焦点时,使用Websocket进行角度冻结

问题描述

我们有一个Angular 8项目,该项目具有一个Websocket,其中不断传入数据流。数据存储在clientInfo对象中,并且更改通过{{service.clientInfo.variable立即反映在页面中。 }}。唯一的问题是,当我转到浏览器中的另一个选项卡并返回该页面时,有时页面需要花费几秒钟的时间才能赶上,并且直到那时一切都没有响应。

如果我将浏览器选项卡保留为更长的时间,那么我的所有组件都将被隐藏,并且整个选项卡将永久冻结,因此我必须重新打开它(chrome)。我注意到,如果我转到网站的其他部分而不显示websocket的数据,则不会发生这种情况。对我来说,变更检测似乎在缓冲所有内容,并且在浏览器选项卡没有焦点时不进行任何DOM更改,最终耗尽了内存。

我想我也许可以尝试使用文档的“ visibilitychange”事件来检测何时隐藏了浏览器选项卡,然后设置显示/隐藏布尔值。我试图用一个* ngIf与标志以隐藏显示该段WebSocket的数据,但是当标签失去焦点时,ngIf没有及时将其隐藏。

有没有简单的解决方案?我能以某种方式告诉角停止ClientInfo客户对象的变化检测,当标签处于非活动状态?我以为我可以使用前面提到的可视性标志,以存储在不同的对象传入的WebSocket数据,然后在选项卡中重新获得焦点,我可以与主ClientInfo客户端对象合并这些值,但我敢肯定,必须有一个简单的解决方案。

对其设置进行更清晰的编辑:

这是我们服务中的clientInfo对象的简化版本,它有更多功能,但是流是在相关页面显示的部分:

clientInfo = {
  streams: [
    { id: 1,count: 123 },{ id: 2,count: 456 }
  ]
};

然后页面显示此数据(再次简化),如下所示:

<li *ngFor="let stream of service.streams">
  {{ stream.count }}
</li>

streams值是我们服务中的getter,其设置如下:

get streams(): DataStream[] {
  if(this.clientInfo) {
    return this.clientInfo.streams;
  }
  return [];
}

我们使用吸气剂的原因是因为该路径实际上比clientInfo.streams长,为简单起见,我只是这样写它。

网络套接字发送增量更新,以便我们循环浏览流,检查ID是否匹配并更新计数。

预先感谢, 克里斯。

解决方法

抱歉,我想我的问题简化得太多了。我省略了在ngFor循环中使用的ngx-charts(https://github.com/swimlane/ngx-charts)组件。当我注释掉更新clientInfo对象中图形数据的代码时,页面停止冻结。

ngx图表必须一直要求d3一次又一次地更新图形,但标签不会被聚焦。并不是很多人会这样做,但我想要指出的是,当没人看到您的标签时,请勿更新ngx图。