我有一个网络套接字,目前正在以每秒约45条的速度流式传输消息。在这个水平上,它会完全杀死铬。浏览器窗口中的所有功能均已锁定。
我缩减了实现以尝试查找此问题的根本原因,怀疑这可能是我处理这些消息的方式(或Angular中的更新/更改检测)存在问题。
但是现在我有了最简单的websocket实现,可以得到:
this.socket = new WebSocket('ws://localhost:5000/ws');
let i = 0;
this.socket.onmessage = (e: MessageEvent) => {
i++;
if (i % 100 === 0) {
console.log('recieved' + i);
}
};
Run Code Online (Sandbox Code Playgroud)
这是在Angular Injectable中,但没有任何交互作用。
它每100条消息就会将其写入控制台。这仍然会杀死100%CPU使用率的浏览器,在我停止消息流之前,大部分时间它甚至都不会输出到控制台,然后一切都赶上了,并喷出了几行“收到的x00”消息。
消息本身是JSON,如下所示:
{
"Topic":"2a736d15-a2fe-43b2-8e8b-ee888f15a53a","Type":1,
"Message": {
"Value":2,
"Timestamp":"2017-06-05T14:46:21.615062+01:00"
}
}
Run Code Online (Sandbox Code Playgroud)
它们通常约为126个字符。
我以为websockets每秒可以处理成千上万条消息,但是我在Google上找不到任何明智的指标,这听起来像是不合理的性能吗?
我还签入了CPU事件探查器。当一切都被锁定时,这只是一堵电话,所以我每秒将其拒绝为一条消息:
我在其中一个位置上抛出了一个断点,而且似乎每当触发websocket时Angular都会在做某事,这与Zones有关(这是我的零经验!):
堆栈中的第一件事是Websocket本身上的ZoneTask.invoke,但是随后触发了NgZone,最终,一个非常昂贵的更改/更新链被称为:
这一切怎么可能发生?订阅websocket的7行代码完全独立于Angular的更改检测,对吗?他们没有更改绑定到任何组件的任何值。他们唯一的联系是他们坐在一个内部的方法中@Injectable()
草率定律,一旦我发布问题,我就会得出答案。通常,我会删除它,但是在该主题上找不到太多,因此对某人可能有用。
区域问题。这是一篇有用的博客文章。通常,Angular 2使用区域来驱动其变更检测:
Angular 2使用zone.js的原因是要知道我们的处理程序何时完成,然后NgZone服务(NgZone是包装区域服务的类)会调用ApplicationRef.tick()方法。tick()方法从上到下扫描树组件,并在每个组件中计算模板中存在的表达式。如果表达式的结果与先前的结果不同,则Angular将更新连接到该表达式的DOM属性(从上一个刻度开始)。
一个简单的隔离消息性能的简单解决方案是在区域外运行,从而使用方便的方法检测角度的变化runOutsideAngular:
this.zone.runOutsideAngular(() => {
let i = 0;
this.socket.onmessage = (e: MessageEvent) => {
i++;
if (i % 100 === 0) {
console.log('recieved' + i);
}
};
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1073 次 |
| 最近记录: |