nestjs / nest

A progressive Node.js framework for building efficient, scalable, and enterprise-grade server-side applications with TypeScript/JavaScript 🚀
https://nestjs.com
MIT License
67.69k stars 7.63k forks source link

Websocket gateway decorator performance #801

Closed hellraisercenobit closed 6 years ago

hellraisercenobit commented 6 years ago

I'm submitting a...


[ ] Regression 
[x ] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

@SubscribeMessage callback is really slower than native ws on('message', cb)

Expected behavior

@SubscribeMessage callback should be as fast as conventional native on('message') from ws

Minimal reproduction of the problem with instructions

Just use native socket.on('message', () => ...)

What is the motivation / use case for changing the behavior?

Websockets are used in general for realtime data processing. It's seems @SubscribeMessage is really slower than native approach.

Environment


Nest version: latest


For Tooling issues:
- Node version: 10.1.0
- Platform:  Windows

Others:

kamilmysliwiec commented 6 years ago

Nest uses socket.io underneath which is much slower than native WS implementation. Nevertheless, you are able to switch to native ws using WsAdapter.

hellraisercenobit commented 6 years ago

Currently i'm using the ws-adaptor from here => https://github.com/nestjs/nest/blob/master/bundle/websockets/adapters/ws-adapter.js

If i use custom code inside gateway to use ws client.on('message') it's really faster than the decorator. it should be a little bit slower because of message type filtering but not so much. The issue is really on gateway decorator, not on adapter :)

kamilmysliwiec commented 6 years ago

It has to be slower. Take a look here: https://stackoverflow.com/questions/47733390/nestjs-vs-plain-express-performance/48226084#48226084 Almost the same applies to the websockets, except body-parser. Instead, we need to check the passed value, parse json, delegate to the proper handler, check returned value, filter nil (undefined/null), await/subscribe if necessary (Promise/Observable), stringify and so on. A simple comparison with string sent through the network doesn't make sense. Ref:

Which conclusion is to be drawn based on those stats? None, because we aren't used to creating applications that only returns plain strings without any asynchronous stuff. The comparisons with Hello world means nothing, it's only a titbit :)

hellraisercenobit commented 6 years ago

Mmmmm, @kamilmysliwiec, you misunderstood the issue. I have forked the ws adapter and the gateway to use only arraybuffer as direct input without any transform. No filter, no JSON.parse and a single handler. And it's slow on local. Yes, i know, it has to be slower due to wrappers but not so much.

hellraisercenobit commented 6 years ago

I have the answer :) I was using switchMap instead mergeMap for bindMessageHandlers! That's change everything. Sorry for that.

kamilmysliwiec commented 6 years ago

Glad you found the solution 🙂

lock[bot] commented 5 years ago

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.