Angular 当浏览器选项卡没有焦点时使用 Websocket 冻结

Angular Freezing With Websocket When Browser Tab Doesn't Have Focus

我们有一个 Angular 8 项目,它有一个 websocket,有源源不断的数据流进来。数据存储在 clientInfo 对象中,更改会立即反映在页面中,并带有 { { service.clientInfo.variable }}。唯一的问题是,当我转到浏览器中的另一个选项卡并返回页面时,有时页面需要几秒钟才能赶上,直到那时一切都没有响应。

如果我让浏览器选项卡长时间处于非活动状态,我的所有组件都会被隐藏,整个选项卡将永久冻结,我必须重新打开它 (chrome)。我注意到,如果我转到网站的另一部分不显示来自 websocket 的数据,则不会发生这种情况。对我来说,这似乎是更改检测正在缓冲所有内容,并且在浏览器选项卡没有焦点时不进行任何 DOM 更改,最终 运行 内存不足。

我想我也许可以尝试使用文档的“visibilitychange”事件来检测浏览器选项卡何时隐藏,然后设置一个 show/hide 布尔值。我尝试使用该标志的 *ngif来隐藏显示WebSocket数据的部分,但是当Tab丢失焦点时,NGIF不会及时隐藏它。

有什么简单的解决办法吗?我能否以某种方式告诉 Angular 在选项卡未处于活动状态时停止对 clientInfo 对象的更改检测?我认为我可以使用前面提到的可见度标志将传入的Websocket数据存储在其他对象中,然后当Tab Rege Rege focus时,我可以将这些值与Main ClientInfo对象合并,但是我敢肯定必须有一个更简单的解决方案。

编辑以更清楚地了解它的设置方式:

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

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

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

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

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

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

我们使用getter的原因是路径实际上比clientInfo.streams长,为了简单起见,我就这样写了。

websocket 发送增量更新,因此我们循环遍历流,检查 id 是否匹配,并更新计数。

提前致谢, 克里斯

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

ngx-charts 一定是一直在要求 d3 一遍又一遍地更新图形,但没有聚焦选项卡。不会有多少人这样做,但我想要点是,不要在没有人能看到您的标签时更新 ngx-charts。