2
\$\begingroup\$

The application's aim is to transfer drawings from the client canvas to the admin canvas using web sockets, as smoothly as possible. At every mousemove event, the client canvas is compressed to .png and sent to the server through a websocket to finally arrive in the admin window where the image is drawn into the admin canvas.

Actually, the code lags a little in the admin window. It seems the bottleneck is ctx.drawImage() but I am not sure.

I wonder if there is a way to first find the bottleneck and then a way to optimise the transfer with debounce or web workers or other.

Client side:

<canvas id="clientCanvas" style="position: absolute; top: 0px; left: 0px;" width="1563" height="528">

function onMouseMove (e) {
    var canvas = document.getElementById('clientCanvas');
    var ctx = canvas.getContext("2d");
    var imageData = canvas.toDataURL("image/png");

    socket.emit('SS_onMouseMove', {imageData: imageData});
};

admin side:

<canvas id="adminCanvas" style="position: absolute; top: 0px; left: 0px;" width="1563" height="528">

var canvas = document.getElementById("adminCanvas");
var ctx = canvas.getContext("2d");
var image = new Image();
image.onload = function() {
   ctx.clearRect(0, 0, canvas.width, canvas.height);
   ctx.drawImage(image, 0, 0);
};

socket.on("SS_onMouseMove", function(response) { onClientMouseMove(response); });

function onClientMouseMove(response){
    image.src = response.imageData;
}
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

The biggest bottleneck here is the fact that your read and emit are hooked to a mouseMove. Even the slightest movement will cause a lot of reads, as well as flood your server. The next problem would be canvas size. The larger the canvas, the longer reading operations will take and the bigger the transfer will be. And of course, you have network latency which you really can't avoid.

You can debounce. If you happen to use Lodash, there's a debounce function you can use to execute only until a certain period has elapsed since last call. That way, you won't be flooding operations. The side effect is that it's not "live" as it will only transmit if the client pauses. But half a second isn't that bad of a pause though.

\$\endgroup\$
1
  • \$\begingroup\$ You are right. After some readings I realize the best is too emit only the canvas image once at start, and then I'll emit only the client mouse events to reproduce the drawings on admin side using the same code used in client side. \$\endgroup\$ Jan 15, 2016 at 15:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.