I have an Angular MatTable that is displaying events from a websocket. I'd like to have the DOM update and keep up with the events coming from the socket which can exceed 100 messages per second. I believe the Angular virtual DOM can't keep up and instead does a forced refresh a few times per second. To properly display the effect of the websocket feed I need to keep up with the data (no matter how illegible it may be).
In the code below I'm receiving messages via a RxJS WebSocketSubject
which are pushed to serverMessages
. I'm only displaying the most recent 10 messages.
export class FeedComponent {
public serverMessages: Message[] = [{type: "application", data: "Connecting to message stream"}];
public displayedColumns: string[] = ['type', 'data'];
private socket$: WebSocketSubject<Message>;
constructor(private detectorRef: ChangeDetectorRef) {
this.socket$ = new WebSocketSubject(`ws://${env.gatewayHost}/api/liveupdates`);
this.socket$
.subscribe(
(message) => {
this.serverMessages.push(message)
if(this.serverMessages.length > 9) this.serverMessages.shift()
this.serverMessages = [...this.serverMessages]
},
(err) => console.error(err),
() => console.warn('Completed!')
);
this.socket$.next({type: "filter", data: "*"});
}
}
Is MatTable the right choice for this? Should I just modify the DOM with raw TypeScript? Is there a way to force refresh the DOM with each message or increase the rate?
I can see three ways to go around with this that might it might not work, depending on the performance of the machine where the browser is running. Since you are effectively doing DOM manipulation.
This easy you will not spend resources with the angular checks on your variables and you can start the update whenever you want for your component. https://medium.com/angular-in-depth/boosting-performance-of-angular-applications-with-manual-change-detection-42cb396110fb
You know the drill. Get element by id and appending html directly. It's much faster but you'll have to drop MatTable, change the DOM directly which is discouraged.
I think that this is the most sensible thing. Add an animation looking like new rows are added until the steam stops for at least a second (or more or less you'd have to be the judge of that)
This way the user won't be able to read the information but he couldn't anyway and you won't push the browser to the edge.