Pass canvas content from client to admin using web socket 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:

&lt;canvas id="clientCanvas" style="position: absolute; top: 0px; left: 0px;" width="1563" height="528"&gt;

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:

&lt;canvas id="adminCanvas" style="position: absolute; top: 0px; left: 0px;" width="1563" height="528"&gt;

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;
}
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.